[llvm-commits] [hlvm] r38303 - in /hlvm/trunk: hlvm/AST/ hlvm/CodeGen/ hlvm/Pass/ hlvm/Reader/ test/return0/ test/xml2xml/ tools/hlvm-compiler/

Reid Spencer reid at x10sys.com
Sat Jul 7 17:02:08 PDT 2007


Author: reid
Date: Sat Jul  7 19:02:08 2007
New Revision: 38303

URL: http://llvm.org/viewvc/llvm-project?rev=38303&view=rev
Log:
Get the SelectOp working. HLVM can now make decisions. Adjust test cases for
the new ResultOp operator. Start work on LoopOp by validating its operands.

Modified:
    hlvm/trunk/hlvm/AST/Block.cpp
    hlvm/trunk/hlvm/AST/Block.h
    hlvm/trunk/hlvm/AST/ControlFlow.h
    hlvm/trunk/hlvm/AST/Linkables.h
    hlvm/trunk/hlvm/AST/Node.h
    hlvm/trunk/hlvm/AST/Operator.cpp
    hlvm/trunk/hlvm/AST/Operator.h
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/Pass/Validate.cpp
    hlvm/trunk/hlvm/Reader/HLVM.rng
    hlvm/trunk/test/return0/select.hlx
    hlvm/trunk/test/xml2xml/argscall.hlx
    hlvm/trunk/test/xml2xml/arithmetic.hlx
    hlvm/trunk/test/xml2xml/autovar.hlx
    hlvm/trunk/test/xml2xml/block.hlx
    hlvm/trunk/test/xml2xml/booleanops.hlx
    hlvm/trunk/test/xml2xml/break.hlx
    hlvm/trunk/test/xml2xml/call.hlx
    hlvm/trunk/test/xml2xml/continue.hlx
    hlvm/trunk/test/xml2xml/loop.hlx
    hlvm/trunk/tools/hlvm-compiler/hlvm-compiler.cpp

Modified: hlvm/trunk/hlvm/AST/Block.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Block.cpp?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Block.cpp (original)
+++ hlvm/trunk/hlvm/AST/Block.cpp Sat Jul  7 19:02:08 2007
@@ -47,8 +47,10 @@
   if (llvm::isa<AutoVarOp>(child)) {
     AutoVarOp* av = llvm::cast<AutoVarOp>(child);
     autovars[av->getName()] = av;
-  } else if (llvm::isa<ResultOp>(child))
-  type = getResultType(); // update type to match type of thing just added
+  } else if (llvm::isa<ResultOp>(child)) {
+    result = llvm::cast<Operator>(child);
+    type = result->getType();
+  }
 }
 
 void 

Modified: hlvm/trunk/hlvm/AST/Block.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Block.h?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Block.h (original)
+++ hlvm/trunk/hlvm/AST/Block.h Sat Jul  7 19:02:08 2007
@@ -51,7 +51,7 @@
   /// @name Constructors
   /// @{
   protected:
-    Block() : MultiOperator(BlockID){}
+    Block() : MultiOperator(BlockID), label(), result(0), autovars() {}
     virtual ~Block();
 
   /// @}
@@ -60,9 +60,14 @@
   public:
     virtual const Type* getType() const { return this->back()->getType(); }
     const std::string& getLabel() const { return label; }
-    AutoVarOp*   getAutoVar(const std::string& name) const; 
-    const Type* getResultType() { return this->back()->getType(); }
+    AutoVarOp* getAutoVar(const std::string& name) const; 
+    const Type* getResultType() const { return result->getType(); }
+    const Operator* getResult() const { return result; }
     Block* getParentBlock() const;
+    bool isTerminated() const { 
+      if (empty()) return false; 
+      return back()->isTerminator();
+    }
     static inline bool classof(const Block*) { return true; }
     static inline bool classof(const Node* N) { return N->is(BlockID); }
 
@@ -71,6 +76,7 @@
   /// @{
   public:
     void setLabel(const std::string& l) { label = l; }
+
   protected:
     virtual void insertChild(Node* child);
     virtual void removeChild(Node* child);
@@ -80,6 +86,7 @@
   private:
     typedef std::map<std::string,AutoVarOp*> AutoVarMap;
     std::string label;
+    Operator* result;
     AutoVarMap  autovars;
   /// @}
   friend class AST;

Modified: hlvm/trunk/hlvm/AST/ControlFlow.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/ControlFlow.h?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/ControlFlow.h (original)
+++ hlvm/trunk/hlvm/AST/ControlFlow.h Sat Jul  7 19:02:08 2007
@@ -62,8 +62,14 @@
 /// operand as a boolean. If the result is true, the second operand is evaluated
 /// and its result is the result of the select operator. If the result of the
 /// first operand is false, the third operand is evaluated and its result is the
-/// result of the select operator. This is similar to an "if" statement in other
-/// languages except it is unrestricted. The three operands can be of any type.
+/// result of the select operator. This is similar to the ternary operator in
+/// other languages, such as ?: in C.  It also fulfills the purpose of an "if"
+/// statement except it is more generalized because the operator has a result
+/// value whereas most "if" statements do not. The second and third operands 
+/// can be any type but they must both be the same type. If the second and 
+/// third operands are blocks, and neither contains a result operator, the
+/// result of those blocks has type "void" and consequently so does the result
+/// of the select operator.
 /// @brief AST Select Operator Node
 class SelectOp : public TernaryOperator
 {

Modified: hlvm/trunk/hlvm/AST/Linkables.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Linkables.h?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Linkables.h (original)
+++ hlvm/trunk/hlvm/AST/Linkables.h Sat Jul  7 19:02:08 2007
@@ -167,6 +167,7 @@
     bool hasBlock() const { return block != 0; }
     Block* getBlock() const { return block; }
     const SignatureType* getSignature() const;
+    const Type* getResultType() const { return getSignature()->getResultType();}
 
     static inline bool classof(const Function*) { return true; }
     static inline bool classof(const Node* N) { return N->isFunction(); }

Modified: hlvm/trunk/hlvm/AST/Node.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Node.h?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.h (original)
+++ hlvm/trunk/hlvm/AST/Node.h Sat Jul  7 19:02:08 2007
@@ -380,8 +380,7 @@
       return id >= FirstOperatorID && id <= LastOperatorID; }
 
     inline bool isTerminator() const {
-      return (id >= BreakOpID && id <= ContinueOpID) || 
-             (id >= ReturnOpID && id <= ThrowOpID); }
+      return (id >= BreakOpID && id <= ReturnOpID) || (id == ThrowOpID); }
 
     inline bool isNilaryOperator() const {
       return id >= FirstNilaryOperatorID && id <= LastNilaryOperatorID; }

Modified: hlvm/trunk/hlvm/AST/Operator.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Operator.cpp?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Operator.cpp (original)
+++ hlvm/trunk/hlvm/AST/Operator.cpp Sat Jul  7 19:02:08 2007
@@ -29,6 +29,7 @@
 
 #include <hlvm/AST/Operator.h>
 #include <hlvm/AST/Linkables.h>
+#include <hlvm/AST/ControlFlow.h>
 #include <hlvm/Base/Assert.h>
 #include <llvm/Support/Casting.h>
 
@@ -45,6 +46,8 @@
 {
   Node* p = getParent();
   while (p && !isa<Function>(p)) p = p->getParent();
+  if (!p)
+    return 0;
   return cast<Function>(p);
 }
 
@@ -53,9 +56,21 @@
 {
   Node* p = getParent();
   while (p && !isa<Block>(p)) p = p->getParent();
+  if (!p)
+    return 0;
   return cast<Block>(p);
 }
 
+LoopOp*
+Operator::getContainingLoop()
+{
+  Node* p = getParent();
+  while (p && !isa<LoopOp>(p)) p = p->getParent();
+  if (!p)
+    return 0;
+  return cast<LoopOp>(p);
+}
+
 NilaryOperator::~NilaryOperator()
 {
 }

Modified: hlvm/trunk/hlvm/AST/Operator.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Operator.h?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Operator.h (original)
+++ hlvm/trunk/hlvm/AST/Operator.h Sat Jul  7 19:02:08 2007
@@ -38,6 +38,7 @@
 class Type; 
 class Function;
 class Block;
+class LoopOp;
 
 /// This class is the abstract base class in the Abstract Syntax Tree for all
 /// operators. An Operator is an instruction to the virtual machine to take
@@ -74,6 +75,9 @@
     /// Return the block containing this operator
     Block* getContainingBlock();
 
+    /// Return the loop operator containing this operator
+    LoopOp* getContainingLoop();
+
     /// Determine if this is a classof some other type.
     static inline bool classof(const Operator*) { return true; }
     static inline bool classof(const Node* N) { return N->isOperator(); }

Modified: hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:02:08 2007
@@ -77,7 +77,7 @@
   typedef std::vector<llvm::Module*> ModuleList;
   typedef std::vector<llvm::Value*> OperandList;
   typedef std::vector<llvm::BasicBlock*> BlockStack;
-  typedef std::vector<llvm::Value*> ResultStack;
+  typedef std::map<llvm::BasicBlock*,llvm::Value*> ResultDictionary;
   typedef std::map<const hlvm::Variable*,llvm::Value*> VariableDictionary;
   typedef std::map<const hlvm::AutoVarOp*,llvm::Value*> AutoVarDictionary;
   typedef std::map<const hlvm::ConstantValue*,llvm::Constant*> 
@@ -89,7 +89,7 @@
   llvm::BasicBlock* lblk;    ///< The current LLVM block we're generating
   OperandList lops;          ///< The current list of instruction operands
   BlockStack blocks;         ///< The stack of blocks we're constructing
-  ResultStack results;       ///< The stack of block results
+  ResultDictionary results;  ///< Dictionary of LLVM blocks to result values
   VariableDictionary gvars;  ///< Dictionary of HLVM -> LLVM gvars
   AutoVarDictionary lvars;   ///< Dictionary of HLVM -> LLVM auto vars
   llvm::TypeSymbolTable ltypes; ///< The cached LLVM types we've generated
@@ -1112,23 +1112,74 @@
   llvm::Value* op3 = lops.back(); lops.pop_back();
   llvm::Value* op2 = lops.back(); lops.pop_back();
   llvm::Value* op1 = lops.back(); lops.pop_back();
-  hlvmAssert(op1->getType() == llvm::Type::BoolTy);
   hlvmAssert(op2->getType() == op2->getType());
   hlvmAssert(llvm::isa<llvm::BasicBlock>(op2) == 
              llvm::isa<llvm::BasicBlock>(op3));
-  if (llvm::isa<llvm::BasicBlock>(op2)) {
-    // both are blocks, emit a BranchInstr
-    lops.push_back(new llvm::BranchInst(
-      llvm::cast<llvm::BasicBlock>(op2),
-      llvm::cast<llvm::BasicBlock>(op3),op1,lblk));
-    return;
-  } 
 
-  // A this point, we can only be left with a first class type since all HLVM
-  // operators translate to a first class type. Since the select operator
-  // requires first class types, its okay to just use it here.
-  hlvmAssert(op2->getType()->isFirstClassType());
-  lops.push_back(new llvm::SelectInst(op1,op2,op3,"select",lblk));
+  /// If the first operand is a basic block then it is an expression block, by
+  /// definition. We can therefore discard the LLVM basic block and incorporate
+  /// its contents into the current block. We also replace "op1" with the 
+  /// BasicBlock's result which was cached.
+  if (llvm::BasicBlock* BB1 = llvm::dyn_cast<llvm::BasicBlock>(op1)) {
+    hlvmAssert(!BB1->getTerminator() && "expression block with terminator?");
+    // Move the contents of the basic block into the current one
+    llvm::BasicBlock::InstListType& IL = lblk->getInstList();
+    for (llvm::BasicBlock::iterator I = BB1->begin(), E = BB1->end();
+         I != E; )  {
+      // be careful with iterator invalidation
+      llvm::Instruction* one2move = &(*I);
+      ++I;
+      // move the instruction from one block to the other
+      one2move->removeFromParent();
+      IL.push_back(one2move);
+    }
+    op1 = results[BB1];
+    results.erase(BB1);
+    BB1->eraseFromParent();
+  }
+
+  if (llvm::isa<llvm::BasicBlock>(op2)) {
+    // Both op2 and op3 are blocks, so we must emit a branch instruction for 
+    // the select.  That will terminate the current block so we need to set up
+    // another block to receive the result of the selection.  We also need to 
+    // make sure that the two operand blocks are properly terminated.
+    llvm::BasicBlock* BB2 = llvm::cast<llvm::BasicBlock>(op2);
+    llvm::BasicBlock* BB3 = llvm::cast<llvm::BasicBlock>(op3);
+    // Neither block should have a terminator, they are expression blocks
+    hlvmAssert(!BB2->getTerminator() && !BB3->getTerminator());
+    // Create an auto variable to hold the result of the select.
+    llvm::AllocaInst* select_result = new llvm::AllocaInst(
+      /*Ty=*/ results[BB2]->getType(),
+      /*ArraySize=*/ llvm::ConstantUInt::get(llvm::Type::UIntTy,1),
+      /*Name=*/ "select_result",
+      /*InsertAtEnd=*/ lblk
+    );
+    // Set up the branch to terminate the current block
+    new llvm::BranchInst(BB2,BB3,op1,lblk);
+    // Create the exit block
+    llvm::BasicBlock* exit = new llvm::BasicBlock("select_exit",lfunc);
+    // Make the exit block the current block
+    lblk = exit;
+    // Store the result of the "true" case into the autovar
+    new llvm::StoreInst(results[BB2],select_result,BB2);
+    // Branch to the exit block
+    BB2->setName("select_true");
+    new llvm::BranchInst(exit,BB2);
+    // Store the result of the "false" case into the autovar
+    new llvm::StoreInst(results[BB3],select_result,BB3);
+    // Branch to the exit block
+    BB3->setName("select_false");
+    new llvm::BranchInst(exit,BB3);
+    // Load the result and put it on the operand stack
+    lops.push_back(new llvm::LoadInst(select_result,"select",exit));
+  } else { 
+    // A this point, we can only be left with a first class type since all HLVM
+    // operators translate to a first class type. Since the select operator
+    // requires first class types, its okay to just use it here.
+    hlvmAssert(op2->getType()->isFirstClassType());
+    hlvmAssert(op3->getType()->isFirstClassType());
+    lops.push_back(new llvm::SelectInst(op1,op2,op3,"select",lblk));
+  }
 }
 
 template<> void
@@ -1147,6 +1198,7 @@
   llvm::Value* op3 = lops.back(); lops.pop_back();
   llvm::Value* op2 = lops.back(); lops.pop_back();
   llvm::Value* op1 = lops.back(); lops.pop_back();
+
 }
 
 template<> void
@@ -1164,13 +1216,9 @@
 {
   hlvmAssert(lops.size() >= 1 && "Too few operands for ResultOp");
   llvm::Value* result = lops.back(); lops.pop_back();
-  const llvm::Type* resultTy = result->getType();
-  if (resultTy != lfunc->getReturnType()) {
-    result = new llvm::CastInst(result,lfunc->getReturnType(),"result",lblk);
-  }
   // Save the result value for use in other blocks or as the result of the
   // function
-  results.push_back(result);
+  results[lblk] = result;
 }
 
 template<> void
@@ -1180,8 +1228,14 @@
   llvm::Value* result = 0;
   if (lfunc->getReturnType() != llvm::Type::VoidTy) {
     hlvmAssert(!results.empty() && "No result for function");
-    result = results.back(); results.pop_back();
+    result = results[lblk];
+    const llvm::Type* resultTy = result->getType();
+    if (resultTy != lfunc->getReturnType()) {
+      result = new llvm::CastInst(result,lfunc->getReturnType(),"result",lblk);
+    }
+    hlvmAssert(result && "No result for function");
   }
+
   // RetInst is never the operand of another instruction because it is
   // a terminator and cannot return a value. Consequently, we don't push it
   // on the lops stack.
@@ -1478,7 +1532,6 @@
       case BlockID:
       {
         Block* B = llvm::cast<Block>(n);
-
         lblk = new llvm::BasicBlock(B->getLabel(),lfunc,0);
         blocks.push_back(lblk);
         break;
@@ -1577,6 +1630,7 @@
         lfunc = 0;
         break;
       case BlockID:
+        lops.push_back(lblk);
         blocks.pop_back();
         if (blocks.empty())
           lblk = 0;

Modified: hlvm/trunk/hlvm/Pass/Validate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Pass/Validate.cpp?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Pass/Validate.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Validate.cpp Sat Jul  7 19:02:08 2007
@@ -55,8 +55,8 @@
     ValidateImpl() : Pass(0,Pass::PostOrderTraversal), ast(0) {}
     virtual void handleInitialize(AST* tree) { ast = tree; }
     virtual void handle(Node* b,Pass::TraversalKinds k);
-    inline void error(Node*n, const std::string& msg);
-    inline void warning(Node*n, const std::string& msg);
+    inline void error(const Node*n, const std::string& msg);
+    inline void warning(const Node*n, const std::string& msg);
     inline bool checkNode(Node*);
     inline bool checkType(Type*,NodeIDs id);
     inline bool checkValue(Value*,NodeIDs id);
@@ -67,13 +67,14 @@
     inline bool checkUniformContainer(UniformContainerType* T, NodeIDs id);
     inline bool checkDisparateContainer(DisparateContainerType* T, NodeIDs id);
     inline bool checkLinkable(Linkable* LI, NodeIDs id);
+    inline bool checkExpressionBlock(const Block* B);
 
     template <class NodeClass>
     inline void validate(NodeClass* C);
 };
 
 void 
-ValidateImpl::warning(Node* n, const std::string& msg)
+ValidateImpl::warning(const Node* n, const std::string& msg)
 {
   if (n) {
     const Locator* loc = n->getLocator();
@@ -88,7 +89,7 @@
 }
 
 void 
-ValidateImpl::error(Node* n, const std::string& msg)
+ValidateImpl::error(const Node* n, const std::string& msg)
 {
   if (n) {
     const Locator* loc = n->getLocator();
@@ -249,6 +250,21 @@
   return result;
 }
 
+bool 
+ValidateImpl::checkExpressionBlock(const Block* B)
+{
+  bool result = true;
+  if (!B->getResult()) {
+    error(B,"Expression block without result");
+    result = false;
+  }
+  if (B->isTerminated()) {
+    error(B,"Expression blocks cannot have terminators");
+    result = false;
+  }
+  return true;
+}
+
 template<> inline void
 ValidateImpl::validate(VoidType* n)
 {
@@ -503,10 +519,39 @@
   if (checkValue(n,BlockID))
     if (n->getNumOperands() == 0)
       error(n,"Block with no operands");
-    else
-      for (MultiOperator::iterator I = n->begin(), E = n->end(); I != E; ++I)
-        if (!llvm::isa<Operator>(*I))
+    else {
+      Operator* terminator = 0;
+      Operator* result = 0;
+      for (MultiOperator::iterator I = n->begin(), E = n->end(); I != E; ++I) {
+        if (llvm::isa<ResultOp>(*I))
+          result = *I;
+        else if ((*I)->isTerminator()) {
+          if (terminator)
+            error(n,"Block contains multiple terminators");
+          else
+            terminator = *I;
+        } else if (terminator)
+          error(n,"Block has operators after terminator");
+        else if (!llvm::isa<Operator>(*I))
           error(n,"Block contains non-operator");
+      }
+      if (terminator) {
+        if (llvm::isa<ReturnOp>(terminator)) {
+          if (!result) {
+            Function* F= n->getContainingFunction();
+            if (F->getResultType() != ast->getPrimitiveType(VoidTypeID))
+              error(terminator,"Missing result in return from function");
+          }
+        } else if (result) {
+          warning(result,"Result will not be used in terminated block");
+        }
+      } else if (result) {
+        if (n == n->getContainingFunction()->getBlock())
+          error(result,"Function's main block has result but no return");
+      } else {
+        error(n,"Block does not contain a result or terminator");
+      }
+    }
 }
 
 template<> inline void
@@ -521,12 +566,18 @@
 {
   if (checkOperator(n,ResultOpID,1)) {
     const Function* F = n->getContainingFunction();
-    const Block* B = n->getContainingBlock();
-    if (F->getBlock() == B) {
-      const SignatureType* SigTy = F->getSignature();
-      Operator* res = n->getOperand(0);
-      if (res->getType() != SigTy->getResultType())
-        error(n,"ResultOp operand does not agree in type with Function result");
+    if (!F)
+      error(n,"ResultOp not in Function!");
+    else {
+      const Block* B = n->getContainingBlock();
+      if (!B)
+        error(n,"ResultOp not in a Block");
+      else if (F->getBlock() == B) {
+          const SignatureType* SigTy = F->getSignature();
+          Operator* res = n->getOperand(0);
+          if (res->getType() != SigTy->getResultType())
+            error(n,"Operand does not agree in type with Function result");
+      }
     }
   }
 }
@@ -542,14 +593,18 @@
 ValidateImpl::validate(BreakOp* n)
 {
   if (checkOperator(n,BreakOpID,0))
-    checkTerminator(n);
+    if (checkTerminator(n))
+      if (!n->getContainingLoop())
+        error(n,"Break not within a loop scope");
 }
 
 template<> inline void
 ValidateImpl::validate(ContinueOp* n)
 {
   if (checkOperator(n,ContinueOpID,0))
-    checkTerminator(n);
+    if (checkTerminator(n)) 
+      if (!n->getContainingLoop())
+        error(n,"Continue not within a loop scope");
 }
 
 template<> inline void
@@ -564,11 +619,17 @@
     const Type* Ty3 = Op3->getType();
     if (!isa<BooleanType>(Ty1))
       error(n,"SelectOp expects first operand to be type boolean");
-    else if ( Ty2 != Ty3 )
-      error(n,"Second and third operands for SelectOp must agree in type");
-    else if (isa<Block>(Op2) != isa<Block>(Op3))
+    if (isa<Block>(Op1))
+      checkExpressionBlock(cast<Block>(Op1));
+    if (Ty2 != Ty3)
+      error(n,"Second and third operands for SelectOp must have same type");
+    if (isa<Block>(Op2) != isa<Block>(Op3))
       error(n,"SelectOp requires operands 2 and 3 to both be blocks or "
               "neither be blocks");
+    if (isa<Block>(Op2))
+      checkExpressionBlock(cast<Block>(Op2));
+    if (isa<Block>(Op3))
+      checkExpressionBlock(cast<Block>(Op3));
   }
 }
 
@@ -576,12 +637,19 @@
 ValidateImpl::validate(LoopOp* n)
 {
   if (checkOperator(n,LoopOpID,3)) {
-    const Type* Ty = n->getOperand(0)->getType();
-    if (!isa<BooleanType>(Ty) && !isa<VoidType>(Ty))
+    const Operator* Op1 = n->getOperand(0);
+    const Operator* Op2 = n->getOperand(1);
+    const Operator* Op3 = n->getOperand(2);
+    const Type* Ty1 = Op1->getType();
+    const Type* Ty3 = Op3->getType();
+    if (!isa<BooleanType>(Ty1) && !isa<VoidType>(Ty1))
       error(n,"LoopOp expects first operand to be type boolean or void");
-    Ty = n->getOperand(2)->getType();
-    if (!isa<BooleanType>(Ty) && !isa<VoidType>(Ty))
+    if (!isa<BooleanType>(Ty3) && !isa<VoidType>(Ty3))
       error(n,"LoopOp expects third operand to be type boolean or void");
+    if (isa<Block>(Op1))
+      checkExpressionBlock(cast<Block>(Op1));
+    if (isa<Block>(Op3))
+      checkExpressionBlock(cast<Block>(Op3));
   }
 }
 

Modified: hlvm/trunk/hlvm/Reader/HLVM.rng
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/HLVM.rng?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/HLVM.rng (original)
+++ hlvm/trunk/hlvm/Reader/HLVM.rng Sat Jul  7 19:02:08 2007
@@ -1090,12 +1090,22 @@
 
   <define name="break.elem">
     <element name="break">
+      <optional>
+        <attribute name="id">
+          <ref name="Identifier.type"/>
+        </attribute>
+      </optional>
       <ref name="Documentation.pat"/>
     </element>
   </define>
 
   <define name="continue.elem">
     <element name="continue">
+      <optional>
+        <attribute name="id">
+          <ref name="Identifier.type"/>
+        </attribute>
+      </optional>
       <ref name="Documentation.pat"/>
     </element>
   </define>

Modified: hlvm/trunk/test/return0/select.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/return0/select.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/return0/select.hlx (original)
+++ hlvm/trunk/test/return0/select.hlx Sat Jul  7 19:02:08 2007
@@ -1,27 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/select.hlx">
   <bundle id="select">
-    <constant id="0" type="s32">
-      <dec>0</dec>
-    </constant>
-    <constant id="21" type="s32">
-      <dec>21</dec>
-    </constant>
-    <constant id="42" type="s32">
-      <dec>42</dec>
-    </constant>
+    <constant id="0" type="s32"><dec>0</dec></constant>
+    <constant id="21" type="s32"><dec>21</dec></constant>
+    <constant id="42" type="s32"><dec>42</dec></constant>
+    <constant id="true" type="bool"><true/></constant>
+    <constant id="false" type="bool"><false/></constant>
     <program id="select">
       <block>
         <result>
           <select>
             <block>
-              <ne><ref id="42"/><ref id="21"/></ne>
+              <result>
+                <select>
+                  <ne><ref id="42"/><ref id="21"/></ne>
+                  <ref id="true"/>
+                  <ref id="false"/>
+                </select>
+              </result>
             </block>
             <block>
-              <ref id="0"/>
+              <result><ref id="0"/></result>
             </block>
             <block>
-              <ref id="42"/>
+              <result><ref id="42"/></result>
             </block>
           </select>
         </result>

Modified: hlvm/trunk/test/xml2xml/argscall.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/argscall.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/argscall.hlx (original)
+++ hlvm/trunk/test/xml2xml/argscall.hlx Sat Jul  7 19:02:08 2007
@@ -16,6 +16,9 @@
     <constant id="answer" type="u32">
       <dec>42</dec>
     </constant>
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <function id="none" type="no_args" linkage="external"/>
     <function id="one" type="one_arg" linkage="external"/>
     <function id="two" type="two_arg" linkage="external"/>
@@ -40,6 +43,10 @@
           <ref id="answer"/>
           <ref id="answer"/>
         </call>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/arithmetic.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/arithmetic.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/arithmetic.hlx (original)
+++ hlvm/trunk/test/xml2xml/arithmetic.hlx Sat Jul  7 19:02:08 2007
@@ -4,6 +4,9 @@
     <constant id="one" type="u32">
       <dec>1</dec>
     </constant>
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <program id="unaryarithmetic">
       <block>
         <autovar id="v1" type="u32"/>
@@ -98,6 +101,10 @@
             <ref id="v2"/>
           </load>
         </bnor>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/autovar.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/autovar.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/autovar.hlx (original)
+++ hlvm/trunk/test/xml2xml/autovar.hlx Sat Jul  7 19:02:08 2007
@@ -3,7 +3,13 @@
   <bundle id="autovar">
     <program id="autovar">
       <block>
-        <autovar id="v1" type="u32"/>
+        <autovar id="v1" type="s32"/>
+        <result>
+          <load>
+            <ref id="v1"/>
+          </load>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/block.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/block.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/block.hlx (original)
+++ hlvm/trunk/test/xml2xml/block.hlx Sat Jul  7 19:02:08 2007
@@ -15,16 +15,22 @@
         <result>
           <select>
             <block>
-              <ne>
-                <ref id="0"/>
-                <ref id="21"/>
-              </ne>
+              <result>
+                <ne>
+                  <ref id="0"/>
+                  <ref id="21"/>
+                </ne>
+              </result>
             </block>
             <block>
-              <ref id="42"/>
+              <result>
+                <ref id="42"/>
+              </result>
             </block>
             <block>
-              <ref id="21"/>
+              <result>
+                <ref id="21"/>
+              </result>
             </block>
           </select>
         </result>

Modified: hlvm/trunk/test/xml2xml/booleanops.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/booleanops.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/booleanops.hlx (original)
+++ hlvm/trunk/test/xml2xml/booleanops.hlx Sat Jul  7 19:02:08 2007
@@ -7,6 +7,9 @@
     <constant id="true" type="bool">
       <true/>
     </constant>
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <program id="booleanops">
       <block>
         <autovar id="v1" type="bool" init="true"/>
@@ -96,6 +99,10 @@
             <ref id="v2"/>
           </load>
         </le>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/break.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/break.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/break.hlx (original)
+++ hlvm/trunk/test/xml2xml/break.hlx Sat Jul  7 19:02:08 2007
@@ -1,9 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/return.hlx">
   <bundle id="return">
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <program id="return">
       <block>
-        <break/>
+        <loop>
+          <noop/>
+          <block>
+            <break/>
+          </block>
+          <noop/>
+        </loop>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/call.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/call.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/call.hlx (original)
+++ hlvm/trunk/test/xml2xml/call.hlx Sat Jul  7 19:02:08 2007
@@ -3,11 +3,18 @@
   <bundle id="call">
     <signature id="callee_type" result="void"/>
     <function id="callee" type="callee_type" linkage="external"/>
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <program id="return">
       <block>
         <call>
           <ref id="callee"/>
         </call>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/continue.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/continue.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/continue.hlx (original)
+++ hlvm/trunk/test/xml2xml/continue.hlx Sat Jul  7 19:02:08 2007
@@ -1,9 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/return.hlx">
   <bundle id="return">
+    <constant id="result" type="s32">
+      <dec>0</dec>
+    </constant>
     <program id="return">
       <block>
-        <continue/>
+        <loop>
+          <noop/>
+          <block>
+            <continue/>
+          </block>
+          <noop/>
+        </loop>
+        <result>
+          <ref id="result"/>
+        </result>
+        <ret/>
       </block>
     </program>
   </bundle>

Modified: hlvm/trunk/test/xml2xml/loop.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/loop.hlx?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/test/xml2xml/loop.hlx (original)
+++ hlvm/trunk/test/xml2xml/loop.hlx Sat Jul  7 19:02:08 2007
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/return.hlx">
-  <bundle id="return">
+<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/loop.hlx">
+  <bundle id="loop">
     <constant id="0" type="s32">
       <dec>0</dec>
     </constant>
     <constant id="1" type="s32">
       <dec>1</dec>
     </constant>
-    <program id="return">
+    <program id="loop">
       <block>
         <result>
           <loop>

Modified: hlvm/trunk/tools/hlvm-compiler/hlvm-compiler.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/tools/hlvm-compiler/hlvm-compiler.cpp?rev=38303&r1=38302&r2=38303&view=diff

==============================================================================
--- hlvm/trunk/tools/hlvm-compiler/hlvm-compiler.cpp (original)
+++ hlvm/trunk/tools/hlvm-compiler/hlvm-compiler.cpp Sat Jul  7 19:02:08 2007
@@ -47,8 +47,8 @@
 OutputFilename("o", cl::desc("Override output filename"),
                cl::value_desc("filename"));
 
-static cl::opt<bool> Validate("validate", cl::init(true),
-  cl::desc("Validate input before generating code"));
+static cl::opt<bool> NoValidate("no-validate", cl::init(false),
+  cl::desc("Don't validate input before generating code"));
 
 enum GenerationOptions {
   GenLLVMBytecode,
@@ -117,7 +117,7 @@
     XMLReader* rdr = XMLReader::create(InputFilename);
     rdr->read();
     AST* node = rdr->get();
-    if (node && Validate) {
+    if (node && !NoValidate) {
       if (!validate(node))
         return 3;
     }





More information about the llvm-commits mailing list