[llvm-commits] [hlvm] r38401 - in /hlvm/trunk: hlvm/AST/ hlvm/CodeGen/ hlvm/Pass/ hlvm/Reader/ hlvm/Writer/ test/return0/ test/xml2xml/ tools/hlvm-gentestcase/

Reid Spencer reid at x10sys.com
Sat Jul 7 17:03:01 PDT 2007


Author: reid
Date: Sat Jul  7 19:03:00 2007
New Revision: 38401

URL: http://llvm.org/viewvc/llvm-project?rev=38401&view=rev
Log:
A rather large patch to get hlvm-gentestcase generating test cases that include
a variety of operators instead of just function calls. Some important changes
that accompany this are:
1. AutoVars are now initialized by any expression not just constant expression
2. There is a new "ConvertOp" for handling arithmetic type conversions. This
   generally emits as an LLVM cast operator, but we might do fancier 
   conversions in the future (like array->int gives size of array).
3. The SizeOfOp was implemented in the code generator. It returns the runtime
   size of its argument which can be any value.
4. ReferenceOp became GetOp for consistency, brevity, and clarity. The function
   of this operator has expanded to include fetching not only values, but
   types, as needed by the ConvertOp. This is the first step toward making
   types first-class values.
5. IndexOp became GetFieldOp and GetIndexOp to make a distinction between 
   getting fields of DisparateContainerTypes and elements of UniformDTs. Also
   this eliminates a multi-operand operator (index) and simplifies the 
   implementation of indexing (one index at a time). These have now been
   implemented in the code generator as GetElementPtrInst in LLVM.
6. Implemented the various real number math operations. There's no code gen for
   these yet, but they're now recognized, generated, and printed.
7. The pre/post increment/decrement operators can now operate on any location,
   not just an autovar.
8. Function argument handling in the code generator was implemented.
9. The hlvm::dump(...) function was made more resilient to allow dumping of
   partial trees, detached trees, operator nodes, etc.

Modified:
    hlvm/trunk/hlvm/AST/AST.cpp
    hlvm/trunk/hlvm/AST/AST.h
    hlvm/trunk/hlvm/AST/Arithmetic.cpp
    hlvm/trunk/hlvm/AST/Arithmetic.h
    hlvm/trunk/hlvm/AST/Bundle.cpp
    hlvm/trunk/hlvm/AST/ContainerType.cpp
    hlvm/trunk/hlvm/AST/ContainerType.h
    hlvm/trunk/hlvm/AST/ControlFlow.cpp
    hlvm/trunk/hlvm/AST/Linkables.cpp
    hlvm/trunk/hlvm/AST/Linkables.h
    hlvm/trunk/hlvm/AST/MemoryOps.cpp
    hlvm/trunk/hlvm/AST/MemoryOps.h
    hlvm/trunk/hlvm/AST/Node.cpp
    hlvm/trunk/hlvm/AST/Node.h
    hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/Pass/Pass.cpp
    hlvm/trunk/hlvm/Pass/Pass.h
    hlvm/trunk/hlvm/Pass/Validate.cpp
    hlvm/trunk/hlvm/Reader/HLVM.rng
    hlvm/trunk/hlvm/Reader/XMLReader.cpp
    hlvm/trunk/hlvm/Writer/XMLWriter.cpp
    hlvm/trunk/test/return0/arithmetic.hlx
    hlvm/trunk/test/return0/bitwise.hlx
    hlvm/trunk/test/return0/boolean.hlx
    hlvm/trunk/test/return0/break.hlx
    hlvm/trunk/test/return0/call.hlx
    hlvm/trunk/test/return0/complement.hlx
    hlvm/trunk/test/return0/continue.hlx
    hlvm/trunk/test/return0/helloworld.hlx
    hlvm/trunk/test/return0/loop.hlx
    hlvm/trunk/test/return0/noresult.hlx
    hlvm/trunk/test/return0/resultoverride.hlx
    hlvm/trunk/test/return0/return0.hlx
    hlvm/trunk/test/return0/select.hlx
    hlvm/trunk/test/return0/unless.hlx
    hlvm/trunk/test/return0/until.hlx
    hlvm/trunk/test/return0/unused.hlx
    hlvm/trunk/test/return0/while.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/doc.hlx
    hlvm/trunk/test/xml2xml/helloworld.hlx
    hlvm/trunk/test/xml2xml/loop.hlx
    hlvm/trunk/test/xml2xml/progargs.hlx
    hlvm/trunk/test/xml2xml/return.hlx
    hlvm/trunk/test/xml2xml/select.hlx
    hlvm/trunk/test/xml2xml/switch.hlx
    hlvm/trunk/test/xml2xml/unless.hlx
    hlvm/trunk/test/xml2xml/until.hlx
    hlvm/trunk/test/xml2xml/while.hlx
    hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp

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

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.cpp (original)
+++ hlvm/trunk/hlvm/AST/AST.cpp Sat Jul  7 19:03:00 2007
@@ -740,32 +740,31 @@
 AST::new_AutoVarOp(
     const std::string& name, 
     const Type* Ty, 
-    Constant* init,
     const Locator* loc)
 {
   hlvmAssert(Ty != 0 && "AutoVarOp must have a Type!");
   AutoVarOp* result = new AutoVarOp();
   result->setType(Ty);
   result->setLocator(loc);
-  result->setInitializer(init);
   result->setName(name);
   return result;
 }
 
-ReferenceOp* 
-AST::new_ReferenceOp(const Value* V, const Locator*loc)
+GetOp* 
+AST::new_GetOp(const Documentable* D, const Locator*loc)
 {
-  hlvmAssert(V != 0 && "ReferenceOp must have a Value to reference");
-  ReferenceOp* result = new ReferenceOp();
-  const Type* refType = V->getType();
-  if (llvm::isa<AutoVarOp>(V) || 
-      llvm::isa<Argument>(V) ||
-      llvm::isa<Constant>(V))
-    result->setType(refType);
-  else
+  hlvmAssert(D != 0 && "GetOp must have a Value to reference");
+  GetOp* result = new GetOp();
+  if (llvm::isa<AutoVarOp>(D) || 
+      llvm::isa<Argument>(D) ||
+      llvm::isa<Constant>(D)) {
+    result->setType(llvm::cast<Value>(D)->getType());
+  } else if (llvm::isa<Type>(D)) {
+    result->setType(llvm::cast<Type>(D));
+  } else
     hlvmAssert(!"Invalid referent type");
   result->setLocator(loc);
-  result->setReferent(V);
+  result->setReferent(D);
   return result;
 }
 
@@ -826,7 +825,7 @@
 )
 {
   hlvmAssert(oprnd1 != 0 && "Invalid Operand for BinaryOp");
-  hlvmAssert(oprnd2 != 0 && "Invalid Operand for BinUnaryOp");
+  hlvmAssert(oprnd2 != 0 && "Invalid Operand for BinaryOp");
   OpClass* result = new OpClass();
   result->setLocator(loc);
   result->setType(Ty);
@@ -932,17 +931,37 @@
 AST::new_UnaryOp<PreDecrOp>(Operator* op1, Bundle* B, const Locator* loc);
 
 template PostIncrOp*
-AST::new_UnaryOp<PostIncrOp>(
-    const Type* Ty, Operator* op1, const Locator* loc);
+AST::new_UnaryOp<PostIncrOp>(const Type* Ty, Operator* op1, const Locator* loc);
 template PostIncrOp*
 AST::new_UnaryOp<PostIncrOp>(Operator* op1, Bundle* B, const Locator* loc);
 
 template PostDecrOp*
-AST::new_UnaryOp<PostDecrOp>(
-    const Type* Ty, Operator* op1, const Locator* loc);
+AST::new_UnaryOp<PostDecrOp>(const Type* Ty, Operator* op1, const Locator* loc);
 template PostDecrOp*
 AST::new_UnaryOp<PostDecrOp>(Operator* op1, Bundle* B, const Locator* loc);
 
+template SizeOfOp*
+AST::new_UnaryOp<SizeOfOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template SizeOfOp*
+AST::new_UnaryOp<SizeOfOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template ConvertOp*
+AST::new_BinaryOp<ConvertOp>(
+    const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+
+template<> ConvertOp*
+AST::new_BinaryOp(
+  Operator* oprnd1,  ///< The first operand
+  Operator* oprnd2,  ///< The second operand
+  Bundle* B,         ///< The bundle, for type lookup
+  const Locator* loc ///< The source locator
+)
+{
+  GetOp* get = llvm::cast<GetOp>(oprnd2);
+  const Type*  Ty = llvm::cast<Type>(get->getReferent());
+  return new_BinaryOp<ConvertOp>(Ty,oprnd1,oprnd2,loc);
+}
+
 template AddOp*
 AST::new_BinaryOp<AddOp>(
     const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
@@ -997,6 +1016,92 @@
 template BNorOp*
 AST::new_BinaryOp<BNorOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
 
+// Real Operators
+template IsPInfOp*
+AST::new_UnaryOp<IsPInfOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template IsPInfOp*
+AST::new_UnaryOp<IsPInfOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template IsNInfOp*
+AST::new_UnaryOp<IsNInfOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template IsNInfOp*
+AST::new_UnaryOp<IsNInfOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template IsNanOp*
+AST::new_UnaryOp<IsNanOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template IsNanOp*
+AST::new_UnaryOp<IsNanOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template TruncOp*
+AST::new_UnaryOp<TruncOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template TruncOp*
+AST::new_UnaryOp<TruncOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template RoundOp*
+AST::new_UnaryOp<RoundOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template RoundOp*
+AST::new_UnaryOp<RoundOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template FloorOp*
+AST::new_UnaryOp<FloorOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template FloorOp*
+AST::new_UnaryOp<FloorOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template CeilingOp*
+AST::new_UnaryOp<CeilingOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template CeilingOp*
+AST::new_UnaryOp<CeilingOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template LogEOp*
+AST::new_UnaryOp<LogEOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template LogEOp*
+AST::new_UnaryOp<LogEOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template Log2Op*
+AST::new_UnaryOp<Log2Op>(const Type* Ty, Operator* op1, const Locator* loc);
+template Log2Op*
+AST::new_UnaryOp<Log2Op>(Operator* op1, Bundle* B, const Locator* loc);
+
+template Log10Op*
+AST::new_UnaryOp<Log10Op>(const Type* Ty, Operator* op1, const Locator* loc);
+template Log10Op*
+AST::new_UnaryOp<Log10Op>(Operator* op1, Bundle* B, const Locator* loc);
+
+template SquareRootOp*
+AST::new_UnaryOp<SquareRootOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template SquareRootOp*
+AST::new_UnaryOp<SquareRootOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template CubeRootOp*
+AST::new_UnaryOp<CubeRootOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template CubeRootOp*
+AST::new_UnaryOp<CubeRootOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template FactorialOp*
+AST::new_UnaryOp<FactorialOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template FactorialOp*
+AST::new_UnaryOp<FactorialOp>(Operator* op1, Bundle* B, const Locator* loc);
+
+template PowerOp*
+AST::new_BinaryOp<PowerOp>(const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+template PowerOp*
+AST::new_BinaryOp<PowerOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
+
+template RootOp*
+AST::new_BinaryOp<RootOp>(const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+template RootOp*
+AST::new_BinaryOp<RootOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
+
+template GCDOp*
+AST::new_BinaryOp<GCDOp>(const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+template GCDOp*
+AST::new_BinaryOp<GCDOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
+
+template LCMOp*
+AST::new_BinaryOp<LCMOp>(const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+template LCMOp*
+AST::new_BinaryOp<LCMOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
+
 // Boolean Operators
 template NotOp*
 AST::new_UnaryOp<NotOp>(const Type* Ty, Operator* op1, const Locator* loc);

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

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.h (original)
+++ hlvm/trunk/hlvm/AST/AST.h Sat Jul  7 19:03:00 2007
@@ -55,8 +55,7 @@
 class Pool;
 class Operator;
 class AutoVarOp;
-class ReferenceOp;
-class ConstantReferenceOp;
+class GetOp;
 class URI;
 
 /// This class is used to hold or contain an Abstract Syntax Tree. It forms the
@@ -92,6 +91,10 @@
     const std::string& getSystemID() const { return sysid; }
     const std::string& getPublicID() const { return pubid; }
     Pool* getPool() const { return pool; }
+    /// Provide support for isa<X> and friends
+    static inline bool classof(const AST*) { return true; }
+    static inline bool classof(const Node* N) 
+    { return N->is(TreeTopID); }
 
   /// @}
   /// @name Mutators
@@ -433,7 +436,7 @@
     /// Create a new ConstantPointer node.
     ConstantPointer* new_ConstantPointer(
       const std::string& name,  ///< The name of the constant
-      Bundle* bundle,         ///< The bundle to insert the type into
+      Bundle* bundle,           ///< The bundle to insert the type into
       const Type* type,         ///< The type of the constant pointer
       Constant* referent,       ///< The value pointed to
       const Locator* loc = 0    ///< The source locator
@@ -496,13 +499,12 @@
     AutoVarOp* new_AutoVarOp(
       const std::string& name, ///< Name of the autovar in its scope
       const Type* Ty,          ///< Type of the autovar
-      Constant* init,          ///< Initializer for the autovar
       const Locator* loc       ///< The source locator
     );
 
-    /// Create a new ReferenceOp.
-    ReferenceOp* new_ReferenceOp(
-      const Value* V,       ///< The value being referenced
+    /// Create a new GetOp.
+    GetOp* new_GetOp(
+      const Documentable* D,///< The value or type being referenced
       const Locator*loc = 0 ///< The source locator
     );
 

Modified: hlvm/trunk/hlvm/AST/Arithmetic.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Arithmetic.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Arithmetic.cpp (original)
+++ hlvm/trunk/hlvm/AST/Arithmetic.cpp Sat Jul  7 19:03:00 2007
@@ -28,6 +28,9 @@
 //===----------------------------------------------------------------------===//
 
 #include <hlvm/AST/Arithmetic.h>
+#include <hlvm/AST/MemoryOps.h>
+#include <hlvm/AST/Type.h>
+#include <llvm/Support/Casting.h>
 
 namespace hlvm 
 {
@@ -38,6 +41,8 @@
 PostIncrOp::~PostIncrOp() {}
 PreDecrOp::~PreDecrOp() {}
 PostDecrOp::~PostDecrOp() {}
+SizeOfOp::~SizeOfOp() {}
+ConvertOp::~ConvertOp() {}
 AddOp::~AddOp() {}
 SubtractOp::~SubtractOp() {}
 MultiplyOp::~MultiplyOp() {}

Modified: hlvm/trunk/hlvm/AST/Arithmetic.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Arithmetic.h?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Arithmetic.h (original)
+++ hlvm/trunk/hlvm/AST/Arithmetic.h Sat Jul  7 19:03:00 2007
@@ -175,6 +175,53 @@
   friend class AST;
 };
 
+/// This class provides an Abstract Syntax Tree node that represents a 
+/// SizeOf operator. The SizeOfOp is a unary operator that returns the size, in
+/// bytes, of its operand. The value returned is a constant.
+/// @brief AST SizeOf Operator Node   
+class SizeOfOp : public UnaryOperator
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    SizeOfOp() : UnaryOperator(SizeOfOpID)  {}
+    virtual ~SizeOfOp();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    static inline bool classof(const SizeOfOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(SizeOfOpID); }
+
+  /// @}
+  friend class AST;
+};
+
+/// This class provides an Abstract Syntax Tree node that represents a 
+/// conversion operator. The ConvertOp is a binary operator that converts its
+/// first operand to the type provided in its second operand (which must be
+/// a reference operator to the type).
+/// @brief AST Conversion Operator Node   
+class ConvertOp : public BinaryOperator
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    ConvertOp() : BinaryOperator(ConvertOpID)  {}
+    virtual ~ConvertOp();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    static inline bool classof(const ConvertOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(ConvertOpID); }
+
+  /// @}
+  friend class AST;
+};
+
 /// This class provides an Abstract Syntax Tree node that represents an operator
 /// to add two quantities. The AddOp is a binary operator that
 /// computes the sum of its two operands and returns that value.

Modified: hlvm/trunk/hlvm/AST/Bundle.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Bundle.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Bundle.cpp (original)
+++ hlvm/trunk/hlvm/AST/Bundle.cpp Sat Jul  7 19:03:00 2007
@@ -58,8 +58,10 @@
       unresolvedTypes.erase(ot);
       // getRoot()->old(ot);
     }
-    tlist.push_back(ty);
-    ttable.insert(ty);
+    if (!ttable.lookup(ty->getName())) {
+      tlist.push_back(ty);
+      ttable.insert(ty);
+    }
   } else if (Constant* C = dyn_cast<Constant>(kid)) {
     clist.push_back(C);
     // Constants without names are permitted, but not Linkables

Modified: hlvm/trunk/hlvm/AST/ContainerType.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/ContainerType.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/ContainerType.cpp (original)
+++ hlvm/trunk/hlvm/AST/ContainerType.cpp Sat Jul  7 19:03:00 2007
@@ -76,6 +76,15 @@
   return 0;
 }
 
+unsigned 
+DisparateContainerType::getFieldIndex(const std::string& fldname) const
+{
+  for (const_iterator I = begin(), E = end(); I != E; ++I )
+    if ((*I)->getName() == fldname)
+      return I - begin() + 1;
+  return 0;
+}
+
 void 
 DisparateContainerType::resolveTypeTo(const Type* from, const Type* to)
 {

Modified: hlvm/trunk/hlvm/AST/ContainerType.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/ContainerType.h?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/ContainerType.h (original)
+++ hlvm/trunk/hlvm/AST/ContainerType.h Sat Jul  7 19:03:00 2007
@@ -268,6 +268,10 @@
   public:
     virtual const char* getPrimitiveName() const;
     const NamedType* getField(unsigned index) const { return contents[index]; }
+
+    /// Return the index of a named field starting at 1. If the field is not
+    /// found, returns 0.
+    unsigned getFieldIndex(const std::string& fldname) const;
     /// Methods to support type inquiry via is, cast, dyn_cast
     static inline bool classof(const DisparateContainerType*) { return true; }
     static inline bool classof(const Node* N) { 

Modified: hlvm/trunk/hlvm/AST/ControlFlow.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/ControlFlow.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/ControlFlow.cpp (original)
+++ hlvm/trunk/hlvm/AST/ControlFlow.cpp Sat Jul  7 19:03:00 2007
@@ -84,9 +84,9 @@
 Function* 
 CallOp::getCalledFunction() const
 {
-  hlvmAssert(isa<ReferenceOp>(getOperand(0)));
-  ReferenceOp* refop = cast<ReferenceOp>(getOperand(0));
-  const Value* referent = refop->getReferent();
+  hlvmAssert(isa<GetOp>(getOperand(0)));
+  GetOp* refop = cast<GetOp>(getOperand(0));
+  const Documentable* referent = refop->getReferent();
   hlvmAssert(isa<Function>(referent));
   return const_cast<Function*>(cast<Function>(referent));
 }

Modified: hlvm/trunk/hlvm/AST/Linkables.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Linkables.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Linkables.cpp (original)
+++ hlvm/trunk/hlvm/AST/Linkables.cpp Sat Jul  7 19:03:00 2007
@@ -39,9 +39,18 @@
 Linkable::~Linkable() { }
 Variable::~Variable() { }
 Argument::~Argument() { }
+unsigned 
+Argument::getArgNum() const
+{
+  Node* P = getParent();
+  if (!P || !isa<Function>(P))
+    return 0;
+  return cast<Function>(P)->getArgNum(this);
+}
+
 Function::~Function() { }
 
-Value* 
+Argument* 
 Function::getArgument(const std::string& name) const
 {
   for (const_iterator I = begin(), E = end(); I != E ; ++I )
@@ -50,6 +59,25 @@
   return 0;
 }
 
+Argument* 
+Function::getArgument(unsigned argNum ) const
+{
+  hlvmAssert(argNum < size());
+  return args[argNum];
+}
+
+unsigned
+Function::getArgNum(const Argument* arg) const
+{
+  unsigned num = 1;
+  for (const_iterator I = begin(), E = end(); I != E ; ++I )
+    if ((*I) == arg)
+      return num;
+    else
+      num++;
+  return 0;
+}
+
 void 
 Function::insertChild(Node* kid)
 {

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

==============================================================================
--- hlvm/trunk/hlvm/AST/Linkables.h (original)
+++ hlvm/trunk/hlvm/AST/Linkables.h Sat Jul  7 19:03:00 2007
@@ -153,6 +153,9 @@
   /// @{
   public:
     const std::string& getName() const { return name; }
+    /// Return the 1-based index of this in this function it belongs to. 
+    /// If this is not an argument of any function, returns 0;
+    unsigned getArgNum() const;
     static inline bool classof(const Argument*) { return true; }
     static inline bool classof(const Node* N) { return N->is(ArgumentID); }
 
@@ -212,13 +215,18 @@
       { return static_cast<const SignatureType*>(type); }
     const Type* getResultType() const 
       { return getSignature()->getResultType();}
-    Value* getArgument(const std::string& name) const;
+    Argument* getArgument(const std::string& name) const;
+    Argument* getArgument(unsigned argnum) const;
+
+    /// Return the 1-based index of the \p arg in this function. If \p arg
+    /// is not an argument of this function, returns 0;
+    unsigned getArgNum(const Argument* arg) const;
 
     static inline bool classof(const Function*) { return true; }
     static inline bool classof(const Node* N) { return N->isFunction(); }
 
   /// @}
-  /// @name Iterators
+  /// @name Argument Iteration
   /// @{
   public:
     iterator         begin()       { return args.begin(); }

Modified: hlvm/trunk/hlvm/AST/MemoryOps.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/MemoryOps.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/MemoryOps.cpp (original)
+++ hlvm/trunk/hlvm/AST/MemoryOps.cpp Sat Jul  7 19:03:00 2007
@@ -34,7 +34,7 @@
 LoadOp::~LoadOp() {}
 StoreOp::~StoreOp() {}
 AutoVarOp::~AutoVarOp() {}
-ReferenceOp::~ReferenceOp() {}
+GetOp::~GetOp() {}
 GetIndexOp::~GetIndexOp() {}
 GetFieldOp::~GetFieldOp() {}
 

Modified: hlvm/trunk/hlvm/AST/MemoryOps.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/MemoryOps.h?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/MemoryOps.h (original)
+++ hlvm/trunk/hlvm/AST/MemoryOps.h Sat Jul  7 19:03:00 2007
@@ -174,12 +174,12 @@
 /// variables may be declared to be constant in which case they must have an
 /// initializer and their value is immutable.
 /// @brief AST Automatic Variable Operator
-class AutoVarOp : public NilaryOperator
+class AutoVarOp : public UnaryOperator
 {
   /// @name Constructors
   /// @{
   protected:
-    AutoVarOp() : NilaryOperator(AutoVarOpID), name(), initializer(0) {}
+    AutoVarOp() : UnaryOperator(AutoVarOpID), name() {}
     virtual ~AutoVarOp();
 
   /// @}
@@ -187,9 +187,9 @@
   /// @{
   public:
     const std::string& getName() const { return name; }
-    bool hasInitializer() const { return initializer != 0; }
-    Constant* getInitializer() const { return initializer; }
-    bool isZeroInitialized() const { return initializer == 0; }
+    bool hasInitializer() const { return getOperand(0) != 0; }
+    Operator* getInitializer() const { return getOperand(0); }
+    bool isZeroInitialized() const { return getOperand(0) == 0; }
     static inline bool classof(const AutoVarOp*) { return true; }
     static inline bool classof(const Node* N) { return N->is(AutoVarOpID); }
 
@@ -198,56 +198,55 @@
   /// @{
   public:
     void setName(const std::string& n) { name = n; }
-    void setInitializer(Constant* C) { initializer = C; }
+    void setInitializer(Operator* init) { setOperand(0,init); }
 
   /// @}
   /// @name Data
   /// @{
   protected:
     std::string name;
-    Constant* initializer;
   /// @}
   friend class AST;
 };
 
 /// This class provides an Abstract Syntax Tree node that represents an operator
-/// for obtaining a value. The operator has no operands but has a property 
-/// that is the Value to be referenced. The Value must be an AutoVarOp or one
-/// of the Linkable (Variable, Constant, Function).  This operator
-/// bridges between non-operator Values and Operators. The result of this
-/// operator is the address of the memory object.  Typically this operator is
+/// for getting a value. The operator has no operands but has a property 
+/// that is the Documentable to be retrieved. The retrieved object must be a
+/// Type, or Linkable (Variable, Constant, Function). This operator bridges
+/// bridges between non-operator Documentables and Operators. The result of this
+/// operator is the address of the object.  Typically this operator is
 /// used as the operand of a LoadOp or StoreOp.
 /// @see Variable AutoVarOp Operator Value Linkable LoadOp StoreOp
 /// @brief AST Reference Operator
-class ReferenceOp : public NilaryOperator
+class GetOp : public NilaryOperator
 {
   /// @name Constructors
   /// @{
   protected:
-    ReferenceOp() : NilaryOperator(ReferenceOpID) {}
-    virtual ~ReferenceOp();
+    GetOp() : NilaryOperator(GetOpID) {}
+    virtual ~GetOp();
 
   /// @}
   /// @name Accessors
   /// @{
   public:
-    const Value* getReferent() const { return referent; }
-    static inline bool classof(const ReferenceOp*) { return true; }
+    const Documentable* getReferent() const { return referent; }
+    static inline bool classof(const GetOp*) { return true; }
     static inline bool classof(const Node* N) { 
-      return N->is(ReferenceOpID); 
+      return N->is(GetOpID); 
     }
 
   /// @}
   /// @name Mutators
   /// @{
   public:
-    void setReferent(const Value* ref) { referent = ref; }
+    void setReferent(const Documentable* ref) { referent = ref; }
 
   /// @}
   /// @name Data
   /// @{
   protected:
-    const Value* referent;
+    const Documentable* referent;
   /// @}
   friend class AST;
 };

Modified: hlvm/trunk/hlvm/AST/Node.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Node.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.cpp (original)
+++ hlvm/trunk/hlvm/AST/Node.cpp Sat Jul  7 19:03:00 2007
@@ -34,6 +34,8 @@
 #include <hlvm/Base/Assert.h>
 #include <llvm/Support/Casting.h>
 
+using namespace llvm;
+
 namespace hlvm {
 
 Node::~Node()
@@ -48,7 +50,9 @@
     last = p; 
     p = p->parent; 
   }
-  return llvm::cast<AST>(last);
+  if (isa<AST>(last))
+    return cast<AST>(last);
+  return 0;
 }
 
 Bundle*
@@ -58,7 +62,7 @@
   while (p && !p->is(BundleID)) p = p->getParent();
   if (!p)
     return 0;
-  return llvm::cast<Bundle>(p);
+  return cast<Bundle>(p);
 }
 
 void 

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

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.h (original)
+++ hlvm/trunk/hlvm/AST/Node.h Sat Jul  7 19:03:00 2007
@@ -149,8 +149,8 @@
   PInfOpID,                ///< Constant Positive Infinity Real Value
   NInfOpID,                ///< Constant Negative Infinity Real Value
   NaNOpID,                 ///< Constant Not-A-Number Real Value
-  ReferenceOpID,           ///< Obtain value of Variable/Function/Constant
-LastNilaryOperatorID = ReferenceOpID,
+  GetOpID,                 ///< Obtain value of Variable/Function/Constant
+LastNilaryOperatorID = GetOpID,
 
   // Control Flow Unary Operators
   ResultOpID,              ///< Specify the result of a block or function
@@ -165,7 +165,8 @@
   PostIncrOpID,            ///< Post-Increment Unary Integer Operator
   PreDecrOpID,             ///< Pre-Decrement Unary Integer Operator
   PostDecrOpID,            ///< Post-Decrement Unary Integer Operator
-  SizeOfID,                ///< Size of a constant
+  SizeOfOpID,              ///< Size of a constant
+  ConvertOpID,             ///< Convert one type to another
 
   // Real Arithmetic Unary Operators
   IsPInfOpID,              ///< Real Number Positive Infinity Test Operator
@@ -317,7 +318,8 @@
 
     bool isIntegralType()  const { 
       return (id == IntegerTypeID) || (id == RangeTypeID) || 
-        (id == EnumerationTypeID) || (id == BooleanTypeID);  }
+        (id == EnumerationTypeID) || (id == BooleanTypeID) ||
+        (id == CharacterTypeID); }
 
     bool isNumericType() const {
       return isIntegralType() || id == RealTypeID; }

Modified: hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMEmitter.h Sat Jul  7 19:03:00 2007
@@ -320,6 +320,12 @@
       return llvm::BinaryOperator::create(llvm::Instruction::Xor,
         V, getAllOnes(V->getType()), "cmpl", TheBlock);
     }
+    llvm::Constant* emitSizeOf(llvm::Value* V1) {
+      return llvm::ConstantExpr::getSizeOf(V1->getType());
+    }
+    llvm::Constant* emitSizeof(llvm::Type* Ty) {
+      return llvm::ConstantExpr::getSizeOf(Ty);
+    }
     llvm::BinaryOperator* emitAdd(llvm::Value* V1, llvm::Value* V2) {
       return llvm::BinaryOperator::create(llvm::Instruction::Add, 
         V1, V2, "add", TheBlock);
@@ -405,6 +411,13 @@
       return new llvm::GetElementPtrInst(V,indices,"",TheBlock);
     }
 
+    llvm::GetElementPtrInst* emitGEP(llvm::Value* V, llvm::Value* index) {
+      ArgList indices;
+      indices.push_back(llvm::Constant::getNullValue(llvm::Type::UIntTy));
+      indices.push_back(index);
+      return new llvm::GetElementPtrInst(V,indices,"",TheBlock);
+    }
+
     /// This method implements an assignment of a src value to a pointer to a
     /// destination value. It handles all cases from a simple store instruction
     /// for first class types, to construction of temporary global variables 

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

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:03:00 2007
@@ -114,11 +114,10 @@
   llvm::Constant* getConstant(const hlvm::Constant* C);
   llvm::Value* getVariable(const hlvm::Variable* V);
   llvm::Function* getFunction(const hlvm::Function* F);
+  llvm::Argument* getArgument(const hlvm::Argument* arg);
   inline llvm::GlobalValue::LinkageTypes getLinkageTypes(LinkageKinds lk);
   inline std::string getLinkageName(const Linkable* li);
-  inline llvm::Value* getBoolean(llvm::Value* op);
-  inline llvm::Value* getInteger(llvm::Value* op);
-  inline llvm::Value* getReferent(hlvm::ReferenceOp* r);
+  inline llvm::Value* getReferent(hlvm::GetOp* r);
   inline llvm::Value* toBoolean(llvm::Value* op);
   inline llvm::Value* ptr2Value(llvm::Value* op);
   inline llvm::Value* coerce(llvm::Value* op);
@@ -481,7 +480,7 @@
 }
 
 llvm::Value*
-LLVMGeneratorPass::getVariable(const Variable* V) 
+LLVMGeneratorPass::getVariable(const hlvm::Variable* V) 
 {
   hlvmAssert(V != 0);
   hlvmAssert(V->is(VariableID));
@@ -527,6 +526,26 @@
   );
 }
 
+llvm::Argument*
+LLVMGeneratorPass::getArgument(const hlvm::Argument* arg)
+{
+  unsigned argNum = arg->getArgNum();
+  hlvmAssert(argNum != 0);
+  argNum--;
+  hlvm::Function* hF = llvm::cast<hlvm::Function>(arg->getParent());
+  llvm::Function* lF = getFunction(hF);
+  llvm::Function::ArgumentListType& arglist = lF->getArgumentList();
+  // Bump the argument number to accommodate the first argument being
+  // a pointer to the result, if the type of the result is not first-class.
+  if (!getType(hF->getResultType())->isFirstClassType())
+    argNum++;
+  llvm::Function::arg_iterator I = lF->arg_begin(), E = lF->arg_end();
+  for (; I != E && argNum; ++I, --argNum)
+    ;
+  hlvmAssert(I != E);
+  return I;
+}
+
 llvm::GlobalValue::LinkageTypes
 LLVMGeneratorPass::getLinkageTypes(LinkageKinds lk)
 {
@@ -543,9 +562,9 @@
 }
 
 llvm::Value* 
-LLVMGeneratorPass::getReferent(hlvm::ReferenceOp* r)
+LLVMGeneratorPass::getReferent(hlvm::GetOp* r)
 {
-  hlvm::Value* referent = const_cast<hlvm::Value*>(r->getReferent());
+  const hlvm::Documentable* referent = r->getReferent();
   llvm::Value* v = 0;
   if (llvm::isa<AutoVarOp>(referent)) {
     AutoVarMap::const_iterator I = 
@@ -566,7 +585,9 @@
     hlvmAssert(F && "Function not found?");
     v = F;
   } else if (llvm::isa<Argument>(referent)) {
-    ;
+    llvm::Argument* arg = getArgument(llvm::cast<hlvm::Argument>(referent));
+    hlvmAssert(arg && "Argument not found?");
+    v = arg;
   } else
     hlvmDeadCode("Referent not a linkable or autovar?");
   return v;
@@ -731,12 +752,12 @@
   // alloca is in a block that is in a loop.
   const llvm::Type* elemType = getType(av->getType());
   llvm::Value* alloca = em.NewAutoVar(elemType,av->getName()); 
-  llvm::Constant* C = 0;
+  llvm::Value* init = 0;
   if (av->hasInitializer())
-    C = getConstant(av->getInitializer());
+    init = popOperand(av->getInitializer());
   else
-    C = em.getNullValue(elemType);
-  em.emitAssign(alloca,C);
+    init = em.getNullValue(elemType);
+  em.emitAssign(alloca,init);
   pushOperand(alloca,av);
   lvars[av] = alloca;
 }
@@ -855,6 +876,49 @@
 }
 
 template<> void
+LLVMGeneratorPass::gen(SizeOfOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0));
+  pushOperand(em.emitSizeOf(op1),op);
+}
+
+template<> void
+LLVMGeneratorPass::gen(ConvertOp* op)
+{
+  // Get the value to be converted
+  hlvm::Operator* op1 = op->getOperand(0);
+  // Get the type of the value to be converted
+  const hlvm::Type* srcTy = op1->getType();
+  // Get the llvm Value for the value to be converted
+  llvm::Value* v1 = popOperand(op1);
+  
+  // Get the target type
+  hlvm::GetOp* op2 = llvm::cast<GetOp>(op->getOperand(1));
+  const hlvm::Type* tgtTy = llvm::cast<const hlvm::Type>(op2->getReferent());
+  llvm::Value* v2 = popOperand(op2);
+
+  // Get the source and target types as an llvm type
+  const llvm::Type* lsrcTy = getType(srcTy);
+  const llvm::Type* ltgtTy = getType(tgtTy);
+
+  // First, deal with the easy case of conversion of first class types. This
+  // can just be done with the LLVM cast operator
+  if (lsrcTy->isFirstClassType() && ltgtTy->isFirstClassType()) {
+    pushOperand(em.emitCast(v1,ltgtTy,v1->getName() + "_converted"),op);
+    return;
+  }
+
+  // Okay, this isn't going to be pretty. HLVM gaurantees that an object of
+  // any type is coercible to any other type. The following code makes this
+  // happen.
+  switch (srcTy->getID()) 
+  {
+    default: // FIXME!!
+      hlvmNotImplemented("Conversion of non-first-class types");
+  }
+}
+
+template<> void
 LLVMGeneratorPass::gen(AddOp* op)
 {
   llvm::Value* op1 = popOperand(op->getOperand(0)); 
@@ -1414,7 +1478,7 @@
 }
 
 template<> void
-LLVMGeneratorPass::gen(ReferenceOp* r)
+LLVMGeneratorPass::gen(GetOp* r)
 {
   llvm::Value* referent = getReferent(r);
   pushOperand(referent,r);
@@ -1423,8 +1487,27 @@
 template<> void
 LLVMGeneratorPass::gen(GetFieldOp* i)
 {
-  llvm::Value* location = popOperand(i->getOperand(0));
-  llvm::Value* fld = popOperand(i->getOperand(1));
+  hlvm::Operator* loc = i->getOperand(0);
+  hlvm::Operator* field = i->getOperand(1);
+  if (hlvm::GetOp* Ref = llvm::dyn_cast<GetOp>(field)) 
+    if (const hlvm::Documentable* referent = Ref->getReferent())
+      if (const hlvm::ConstantString* CS = 
+           llvm::dyn_cast<ConstantString>(referent)) {
+        const std::string& fldName = CS->getValue();
+        const DisparateContainerType* DCT = 
+          llvm::cast<DisparateContainerType>(loc->getType());
+        unsigned index = DCT->getFieldIndex(fldName);
+        hlvmAssert(index != 0 && "Invalid field name");
+        llvm::Constant* idx = llvm::ConstantUInt::get(llvm::Type::UIntTy,index);
+        llvm::Value* location = popOperand(loc);
+        pushOperand(em.emitGEP(location,idx),i);
+        return;
+      }
+
+  // The operand is not a constant string. We must look the field up at runtime
+  hlvmNotImplemented("Lookup of field at runtime");
+  llvm::Value* location = popOperand(loc);
+  llvm::Value* fld = popOperand(field);
 }
 
 template<> void
@@ -1432,6 +1515,7 @@
 {
   llvm::Value* location = popOperand(i->getOperand(0));
   llvm::Value* index = popOperand(i->getOperand(1));
+  pushOperand(em.emitGEP(location,index),i);
 }
 
 template<> void
@@ -1693,6 +1777,8 @@
       case PreDecrOpID:             gen(llvm::cast<PreDecrOp>(n)); break;
       case PostIncrOpID:            gen(llvm::cast<PostIncrOp>(n)); break;
       case PostDecrOpID:            gen(llvm::cast<PostDecrOp>(n)); break;
+      case SizeOfOpID:              gen(llvm::cast<SizeOfOp>(n)); break;
+      case ConvertOpID:             gen(llvm::cast<ConvertOp>(n)); break;
       case AddOpID:                 gen(llvm::cast<AddOp>(n)); break;
       case SubtractOpID:            gen(llvm::cast<SubtractOp>(n)); break;
       case MultiplyOpID:            gen(llvm::cast<MultiplyOp>(n)); break;
@@ -1726,7 +1812,7 @@
       case CallOpID:                gen(llvm::cast<CallOp>(n)); break;
       case LoadOpID:                gen(llvm::cast<LoadOp>(n)); break;
       case StoreOpID:               gen(llvm::cast<StoreOp>(n)); break;
-      case ReferenceOpID:           gen(llvm::cast<ReferenceOp>(n)); break;
+      case GetOpID:                 gen(llvm::cast<GetOp>(n)); break;
       case AutoVarOpID:             gen(llvm::cast<AutoVarOp>(n)); break;
       case OpenOpID:                gen(llvm::cast<OpenOp>(n)); break;
       case CloseOpID:               gen(llvm::cast<CloseOp>(n)); break;

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

==============================================================================
--- hlvm/trunk/hlvm/Pass/Pass.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Pass.cpp Sat Jul  7 19:03:00 2007
@@ -45,7 +45,7 @@
   PassManagerImpl() : PassManager(), pre(), post() {}
   void addPass(Pass* p);
   virtual void runOn(AST* tree);
-  virtual void runOn(AST* tree, Node* startAt);
+  virtual void runOnNode(Node* startAt);
 
   inline void runIfInterested(Pass* p, Node* n, Pass::TraversalKinds m);
   inline void runPreOrder(Node* n);
@@ -190,16 +190,14 @@
 }
 
 void 
-PassManagerImpl::runOn(AST* tree, Node* startAt)
+PassManagerImpl::runOnNode(Node* startAt)
 {
   // Check to make sure startAt is in tree
-  hlvmAssert(tree != 0 && "Can't run passes on null tree");
   hlvmAssert(startAt != 0 && "Can't run passes from null start");
-  Node* parent = startAt;
-  while (parent->getParent() != 0) parent = parent->getParent();
-  hlvmAssert(parent == tree && "Can't run passes on node that isn't in tree");
 
-  if (isa<Bundle>(startAt))
+  if (isa<AST>(startAt))
+    runOn(cast<AST>(startAt));
+  else if (isa<Bundle>(startAt))
     runOn(cast<Bundle>(startAt));
   else if (isa<Block>(startAt))
     runOn(cast<Block>(startAt));
@@ -207,6 +205,8 @@
     runOn(cast<Linkable>(startAt));
   else if (isa<ConstantValue>(startAt))
     runOn(cast<ConstantValue>(startAt));
+  else if (isa<Operator>(startAt))
+    runOn(cast<Operator>(startAt));
   else
     hlvmAssert(!"startAt type not supported");
 }

Modified: hlvm/trunk/hlvm/Pass/Pass.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Pass/Pass.h?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Pass/Pass.h (original)
+++ hlvm/trunk/hlvm/Pass/Pass.h Sat Jul  7 19:03:00 2007
@@ -126,7 +126,7 @@
     static  PassManager* create();
     virtual void addPass(Pass* p) = 0;
     virtual void runOn(AST* tree) = 0;
-    virtual void runOn(AST* tree, Node* startAt) = 0;
+    virtual void runOnNode(Node* startAt) = 0;
 };
 
 bool validate(AST* tree);

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

==============================================================================
--- hlvm/trunk/hlvm/Pass/Validate.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Validate.cpp Sat Jul  7 19:03:00 2007
@@ -995,13 +995,17 @@
 ValidateImpl::validate(StoreOp* n)
 {
   if (checkOperator(n,StoreOpID,2)) {
-    const Type* Ty1 = n->getOperand(0)->getType();
-    const Type* Ty2 = n->getOperand(1)->getType();
+    Operator* op1 = n->getOperand(0);
+    Operator* op2 = n->getOperand(1);
+    const Type* Ty1 = op1->getType();
+    const Type* Ty2 = op2->getType();
     if (Ty1 != Ty2) {
       error(n,"StoreOp operands do not agree in type");
-    } else if (const ReferenceOp* ref = 
-               dyn_cast<ReferenceOp>(n->getOperand(0))) {
-      const Value* R = ref->getReferent();
+    } else if (isa<AutoVarOp>(op1)) {
+      if (cast<AutoVarOp>(op1)->isConstant()) 
+        error(n,"Can't store to constant automatic variable");
+    } else if (const GetOp* ref = dyn_cast<GetOp>(n->getOperand(0))) {
+      const Documentable* R = ref->getReferent();
       if (isa<Variable>(R) && cast<Variable>(R)->isConstant())
         error(n,"Can't store to constant variable");
       else if (isa<AutoVarOp>(R) && cast<AutoVarOp>(R)->isConstant())
@@ -1044,13 +1048,13 @@
 }
 
 template<> inline void
-ValidateImpl::validate(ReferenceOp* op)
+ValidateImpl::validate(GetOp* op)
 {
-  if (checkOperator(op,ReferenceOpID,0,true)) {
-    const Value* referent = op->getReferent();
+  if (checkOperator(op,GetOpID,0,true)) {
+    const Documentable* referent = op->getReferent();
     Block* blk = op->getContainingBlock();
     if (!blk)
-      error(op,"ReferenceOp not in a block?");
+      error(op,"GetOp not in a block?");
     else if (const AutoVarOp* ref = dyn_cast<AutoVarOp>(referent)) {
       while (blk != 0) {
         if (AutoVarOp* av = blk->getAutoVar(ref->getName())) 
@@ -1063,15 +1067,21 @@
     } else if (const Argument* arg = dyn_cast<Argument>(referent)) {
       Function* F = op->getContainingFunction();
       if (!F)
-        error(op,"ReferenceOp not in a function?");
+        error(op,"GetOp not in a function?");
       else if (F->getArgument(arg->getName()) != arg)
         error(F,"Referent does not match function argument");
     } else if (const Constant* cval = dyn_cast<Constant>(referent)) {
       Bundle* B = op->getContainingBundle();
       if (!B)
-        error(op,"ReferenceOp not in a bundle?");
+        error(op,"GetOp not in a bundle?");
       else if (B->getConst(cval->getName()) != cval)
-        error(cval,"Referent does not value found in Bundle");
+        error(cval,"Constant not found in Bundle");
+    } else if (const Type* Ty = dyn_cast<Type>(referent)) {
+      Bundle* B = op->getContainingBundle();
+      if (!B)
+        error(op,"GetOp not in bundle?");
+      else if (B->getType(Ty->getName()) != Ty)
+        error(Ty,"Type not found in Bundle");
     } else {
       error(op,"Referent of unknown kind");
     }
@@ -1102,15 +1112,15 @@
 ValidateImpl::validate(PreIncrOp* n)
 {
   if (checkOperator(n,PreIncrOpID,1)) {
-    if (ReferenceOp* oprnd = llvm::dyn_cast<ReferenceOp>(n->getOperand(0))) {
-      const Value* V = oprnd->getReferent();
+    if (GetOp* oprnd = llvm::dyn_cast<GetOp>(n->getOperand(0))) {
+      const Documentable* V = oprnd->getReferent();
       if (V && (isa<AutoVarOp>(V) || isa<Variable>(V))) {
-        if (!V->getType()->isNumericType())
+        if (!llvm::cast<Value>(V)->getType()->isNumericType())
           error(n,"Target of PostIncrOp is not numeric type");
       } else
         ; // Handled elsewhere
     } else 
-      error(n,"Operand of PostIncrOp must be a ReferenceOp");
+      error(n,"Operand of PostIncrOp must be a GetOp");
   }
 }
 
@@ -1118,15 +1128,15 @@
 ValidateImpl::validate(PostIncrOp* n)
 {
   if (checkOperator(n,PostIncrOpID,1)) {
-    if (ReferenceOp* oprnd = llvm::dyn_cast<ReferenceOp>(n->getOperand(0))) {
-      const Value* V = oprnd->getReferent();
+    if (GetOp* oprnd = llvm::dyn_cast<GetOp>(n->getOperand(0))) {
+      const Documentable* V = oprnd->getReferent();
       if (V && (isa<AutoVarOp>(V) || isa<Variable>(V))) {
-        if (!V->getType()->isNumericType())
+        if (!llvm::cast<Value>(V)->getType()->isNumericType())
           error(n,"Target of PostIncrOp is not numeric type");
       } else
         ; // Handled elsewhere
     } else 
-      error(n,"Operand of PostIncrOp must be a ReferenceOp");
+      error(n,"Operand of PostIncrOp must be a GetOp");
   }
 }
 
@@ -1134,15 +1144,15 @@
 ValidateImpl::validate(PreDecrOp* n)
 {
   if (checkOperator(n,PreDecrOpID,1)){
-    if (ReferenceOp* oprnd = llvm::dyn_cast<ReferenceOp>(n->getOperand(0))) {
-      const Value* V = oprnd->getReferent();
+    if (GetOp* oprnd = llvm::dyn_cast<GetOp>(n->getOperand(0))) {
+      const Documentable* V = oprnd->getReferent();
       if (V && (isa<AutoVarOp>(V) || isa<Variable>(V))) {
-        if (!V->getType()->isNumericType())
+        if (!llvm::cast<Value>(V)->getType()->isNumericType())
           error(n,"Target of PreDecrOp is not numeric type");
       } else
         ; // Handled elsewhere
     } else 
-      error(n,"Operand of PreDecrOp must be a ReferenceOp");
+      error(n,"Operand of PreDecrOp must be a GetOp");
   }
 }
 
@@ -1150,15 +1160,36 @@
 ValidateImpl::validate(PostDecrOp* n)
 {
   if (checkOperator(n,PostDecrOpID,1)) {
-    if (ReferenceOp* oprnd = llvm::dyn_cast<ReferenceOp>(n->getOperand(0))) {
-      const Value* V = oprnd->getReferent();
+    if (GetOp* oprnd = llvm::dyn_cast<GetOp>(n->getOperand(0))) {
+      const Documentable* V = oprnd->getReferent();
       if (V && (isa<AutoVarOp>(V) || isa<Variable>(V))) {
-        if (!V->getType()->isNumericType())
+        if (!llvm::cast<Value>(V)->getType()->isNumericType())
           error(n,"Target of PostDecrOp is not numeric type");
       } else
         ; // Handled elsewhere
     } else 
-      error(n,"Operand of PostDecrOp must be a ReferenceOp");
+      error(n,"Operand of PostDecrOp must be a GetOp");
+  }
+}
+
+template<> inline void
+ValidateImpl::validate(SizeOfOp* n)
+{
+  if (checkOperator(n,SizeOfOpID,2))
+    ;
+}
+
+template<> inline void
+ValidateImpl::validate(ConvertOp* n)
+{
+  if (checkOperator(n,ConvertOpID,2)) {
+    const Operator* Oprnd1 = n->getOperand(0);
+    const Operator* Oprnd2 = n->getOperand(1);
+    if (const GetOp* RO = dyn_cast<GetOp>(Oprnd2)) {
+      if (!isa<Type>(RO->getReferent()))
+        error(n,"Second operand must be a reference to atype");
+    } else
+      error(n,"Second operand must be a GetOp");
   }
 }
 
@@ -1656,7 +1687,7 @@
     case AllocateOpID:           validate(cast<AllocateOp>(n)); break;
     case DeallocateOpID:         validate(cast<DeallocateOp>(n)); break;
     case ReallocateOpID:         /*validate(cast<ReallocateOp>(n));*/ break;
-    case ReferenceOpID:          validate(cast<ReferenceOp>(n)); break;
+    case GetOpID:                validate(cast<GetOp>(n)); break;
     case AutoVarOpID:            validate(cast<AutoVarOp>(n)); break;
     case NegateOpID:             validate(cast<NegateOp>(n)); break;
     case ComplementOpID:         validate(cast<ComplementOp>(n)); break;
@@ -1664,6 +1695,8 @@
     case PostIncrOpID:           validate(cast<PostIncrOp>(n)); break;
     case PreDecrOpID:            validate(cast<PreDecrOp>(n)); break;
     case PostDecrOpID:           validate(cast<PostDecrOp>(n)); break;
+    case SizeOfOpID:             validate(cast<SizeOfOp>(n)); break;
+    case ConvertOpID:            validate(cast<ConvertOp>(n)); break;
     case AddOpID:                validate(cast<AddOp>(n)); break;
     case SubtractOpID:           validate(cast<SubtractOp>(n)); break;
     case MultiplyOpID:           validate(cast<MultiplyOp>(n)); break;

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

==============================================================================
--- hlvm/trunk/hlvm/Reader/HLVM.rng (original)
+++ hlvm/trunk/hlvm/Reader/HLVM.rng Sat Jul  7 19:03:00 2007
@@ -500,7 +500,7 @@
       <ref name="vect.elem"/>
       <ref name="struct.elem"/>
       <ref name="cont.elem"/>
-      <ref name="cref.elem"/>
+      <ref name="get.elem"/>
     </choice>
   </define>
 
@@ -636,13 +636,6 @@
     </element>
   </define>
 
-  <define name="cref.elem">
-    <element name="ref">
-      <ref name="Named_Element.pat"/>
-      <ref name="Documentation.pat"/>
-    </element>
-  </define>
-
   <!-- PATTERNS FOR VARIABLES-->
 
   <define name="variable.elem">
@@ -723,6 +716,8 @@
       <ref name="BooleanOperators.pat"/>
       <ref name="UnaryArithmeticOperators.pat"/>
       <ref name="BinaryArithmeticOperators.pat"/>
+      <ref name="UnaryRealMathOperators.pat"/>
+      <ref name="BinaryRealMathOperators.pat"/>
     </choice>
   </define>
 
@@ -734,6 +729,8 @@
       <ref name="BooleanOperators.pat"/>
       <ref name="UnaryArithmeticOperators.pat"/>
       <ref name="BinaryArithmeticOperators.pat"/>
+      <ref name="UnaryRealMathOperators.pat"/>
+      <ref name="BinaryRealMathOperators.pat"/>
       <ref name="MemoryOps.pat"/>
       <ref name="InputOutputOps.pat"/>
       <ref name="ControlFlowOps.pat"/>
@@ -760,7 +757,7 @@
 
   <define name="Location.pat">
     <choice>
-      <ref name="ref.elem"/>
+      <ref name="get.elem"/>
       <ref name="getfld.elem"/>
       <ref name="getidx.elem"/>
     </choice>
@@ -822,12 +819,12 @@
       <ref name="getidx.elem"/>
       <ref name="length.elem"/>
       <ref name="autovar.elem"/>
-      <ref name="ref.elem"/>
+      <ref name="get.elem"/>
     </choice>
   </define>
 
-  <define name="ref.elem">
-    <element name="ref">
+  <define name="get.elem">
+    <element name="get">
       <ref name="Named_Element.pat"/>
       <ref name="Documentation.pat"/>
     </element>
@@ -874,12 +871,10 @@
   <define name="autovar.elem">
     <element name="autovar">
       <ref name="Named_Typed_Element.pat"/>
+      <ref name="Documentation.pat"/>
       <optional>
-        <attribute name="init">
-          <ref name="Identifier.type"/>
-        </attribute>
+        <ref name="Operators.pat"/>
       </optional>
-      <ref name="Documentation.pat"/>
     </element>
   </define>
 
@@ -954,25 +949,25 @@
 
   <define name="preinc.elem">
     <element name="preinc">
-      <ref name="ref.elem"/>
+      <ref name="Location.pat"/>
     </element>
   </define>
 
   <define name="predec.elem">
     <element name="predec">
-      <ref name="ref.elem"/>
+      <ref name="Location.pat"/>
     </element>
   </define>
 
   <define name="postinc.elem">
     <element name="postinc">
-      <ref name="ref.elem"/>
+      <ref name="Location.pat"/>
     </element>
   </define>
 
   <define name="postdec.elem">
     <element name="postdec">
-      <ref name="ref.elem"/>
+      <ref name="Location.pat"/>
     </element>
   </define>
 
@@ -989,6 +984,7 @@
       <ref name="bor.elem"/>
       <ref name="bxor.elem"/>
       <ref name="bnor.elem"/>
+      <ref name="convert.elem"/>
     </choice>
   </define>
 
@@ -1046,6 +1042,144 @@
     </element>
   </define>
 
+  <define name="convert.elem">
+    <element name="convert">
+      <ref name="Operators.pat"/>
+      <ref name="Location.pat"/>
+    </element>
+  </define>
+
+  <!-- Unary Real Math Operators -->
+  <define name="UnaryRealMathOperators.pat">
+    <choice>
+      <ref name="ispinf.elem"/>
+      <ref name="isninf.elem"/>
+      <ref name="isnan.elem"/>
+      <ref name="trunc.elem"/>
+      <ref name="round.elem"/>
+      <ref name="floor.elem"/>
+      <ref name="ceiling.elem"/>
+      <ref name="logE.elem"/>
+      <ref name="log2.elem"/>
+      <ref name="log10.elem"/>
+      <ref name="squareroot.elem"/>
+      <ref name="cuberoot.elem"/>
+      <ref name="factorial.elem"/>
+    </choice>
+  </define>
+
+  <define name="ispinf.elem">
+    <element name="ispinf">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="isninf.elem">
+    <element name="isninf">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="isnan.elem">
+    <element name="isnan">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="trunc.elem">
+    <element name="trunc">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="round.elem">
+    <element name="round">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="floor.elem">
+    <element name="floor">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="ceiling.elem">
+    <element name="ceiling">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="logE.elem">
+    <element name="logE">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="log2.elem">
+    <element name="log2">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="log10.elem">
+    <element name="log10">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="squareroot.elem">
+    <element name="squareroot">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="cuberoot.elem">
+    <element name="cuberoot">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="factorial.elem">
+    <element name="factorial">
+      <ref name="UnaryOperator.pat"/>
+    </element>
+  </define>
+
+  <!-- Binary Real Math Operators -->
+  <define name="BinaryRealMathOperators.pat">
+    <choice>
+      <ref name="power.elem"/>
+      <ref name="root.elem"/>
+      <ref name="GCD.elem"/>
+      <ref name="LCM.elem"/>
+    </choice>
+  </define>
+
+  <define name="power.elem">
+    <element name="power">
+      <ref name="BinaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="root.elem">
+    <element name="root">
+      <ref name="BinaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="GCD.elem">
+    <element name="GCD">
+      <ref name="BinaryOperator.pat"/>
+    </element>
+  </define>
+
+  <define name="LCM.elem">
+    <element name="LCM">
+      <ref name="BinaryOperator.pat"/>
+    </element>
+  </define>
+
   <!-- Comparison Operators -->
 
   <define name="BooleanOperators.pat">

Modified: hlvm/trunk/hlvm/Reader/XMLReader.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/XMLReader.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/XMLReader.cpp (original)
+++ hlvm/trunk/hlvm/Reader/XMLReader.cpp Sat Jul  7 19:03:00 2007
@@ -941,26 +941,23 @@
   std::string name, type;
   getNameType(cur, name, type);
   const Type* Ty = getType(type);
-  const char* init = getAttribute(cur,"init",false);
-  Constant*initializer = 0;
-  if (init) {
-    initializer = bundle->getConst(init);
-    if (!initializer)
-      error(loc,std::string("Initializer '") + init + "' not found .");
-  }
-  AutoVarOp* autovar = ast->AST::new_AutoVarOp(name,Ty,initializer,loc);
-  checkDoc(cur,autovar);
-  return autovar;
+  AutoVarOp* result = ast->AST::new_AutoVarOp(name,Ty,loc);
+  xmlNodePtr child = checkDoc(cur,result);
+  if (child && skipBlanks(child)) {
+    Operator* oprnd1 = parseOperator(child);
+    oprnd1->setParent(result);
+  }
+  return result;
 }
 
-template<> ReferenceOp*
-XMLReaderImpl::parse<ReferenceOp>(xmlNodePtr& cur)
+template<> GetOp*
+XMLReaderImpl::parse<GetOp>(xmlNodePtr& cur)
 {
   std::string id = getAttribute(cur,"id");
   Locator* loc = getLocator(cur);
 
   // Find the referrent variable in a block
-  Value* referent = 0;
+  Documentable* referent = 0;
   for (BlockStack::reverse_iterator I = blocks.rbegin(), E = blocks.rend(); 
        I != E; ++I )
   {
@@ -980,11 +977,15 @@
   if (!referent)
     referent= bundle->getConst(id);
     
-  // Didn't find a linkable? Try an error message for size
+  // Didn't find a linkable? Try a type.
+  if (!referent)
+    referent = bundle->getType(id);
+  
+  // Didn't find a type? Try an error message for size
   if (!referent)
       error(loc,std::string("Referent '") + id + "' not found");
 
-  ReferenceOp* refop = ast->AST::new_ReferenceOp(referent, loc);
+  GetOp* refop = ast->AST::new_GetOp(referent, loc);
   checkDoc(cur,refop);
   return refop;
 }
@@ -1281,6 +1282,24 @@
       case TKN_gt:           op = parseBinaryOp<GreaterThanOp>(cur); break;
       case TKN_ge:           op = parseBinaryOp<GreaterEqualOp>(cur); break;
       case TKN_le:           op = parseBinaryOp<LessEqualOp>(cur); break;
+      case TKN_ispinf:       op = parseUnaryOp<IsPInfOp>(cur); break;
+      case TKN_isninf:       op = parseUnaryOp<IsNInfOp>(cur); break;
+      case TKN_isnan:        op = parseUnaryOp<IsNanOp>(cur); break;
+      case TKN_trunc:        op = parseUnaryOp<TruncOp>(cur); break;
+      case TKN_round:        op = parseUnaryOp<RoundOp>(cur); break;
+      case TKN_floor:        op = parseUnaryOp<FloorOp>(cur); break;
+      case TKN_ceiling:      op = parseUnaryOp<CeilingOp>(cur); break;
+      case TKN_logE:         op = parseUnaryOp<LogEOp>(cur); break;
+      case TKN_log2:         op = parseUnaryOp<Log2Op>(cur); break;
+      case TKN_log10:        op = parseUnaryOp<Log10Op>(cur); break;
+      case TKN_squareroot:   op = parseUnaryOp<SquareRootOp>(cur); break;
+      case TKN_cuberoot:     op = parseUnaryOp<CubeRootOp>(cur); break;
+      case TKN_factorial:    op = parseUnaryOp<FactorialOp>(cur); break;
+      case TKN_power:        op = parseBinaryOp<PowerOp>(cur); break;
+      case TKN_root:         op = parseBinaryOp<RootOp>(cur); break;
+      case TKN_GCD:          op = parseBinaryOp<GCDOp>(cur); break;
+      case TKN_LCM:          op = parseBinaryOp<LCMOp>(cur); break;
+      case TKN_convert:      op = parseBinaryOp<ConvertOp>(cur); break;
       case TKN_select:       op = parseTernaryOp<SelectOp>(cur); break;
       case TKN_switch:       op = parseMultiOp<SwitchOp>(cur); break;
       case TKN_while:        op = parseBinaryOp<WhileOp>(cur); break;
@@ -1299,7 +1318,7 @@
       case TKN_open:         op = parseUnaryOp<OpenOp>(cur); break;
       case TKN_write:        op = parseBinaryOp<WriteOp>(cur); break;
       case TKN_close:        op = parseUnaryOp<CloseOp>(cur); break;
-      case TKN_ref:          op = parse<ReferenceOp>(cur); break;
+      case TKN_get:          op = parse<GetOp>(cur); break;
       case TKN_autovar:      op = parse<AutoVarOp>(cur); break;
       case TKN_block:        op = parse<Block>(cur); break;
       default:

Modified: hlvm/trunk/hlvm/Writer/XMLWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Writer/XMLWriter.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Writer/XMLWriter.cpp (original)
+++ hlvm/trunk/hlvm/Writer/XMLWriter.cpp Sat Jul  7 19:03:00 2007
@@ -705,10 +705,6 @@
   startElement("autovar");
   writeAttribute("id",av->getName());
   writeAttribute("type",av->getType()->getName());
-  if (av->hasInitializer()) {
-    Constant* C = llvm::cast<Constant>(av->getInitializer());
-    writeAttribute("init",C->getName());
-  }
   putDoc(av);
 }
 
@@ -895,6 +891,125 @@
 }
 
 template<> void
+XMLWriterImpl::WriterPass::put(const IsPInfOp* op)
+{
+  startElement("ispinf");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const IsNInfOp* op)
+{
+  startElement("isninf");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const IsNanOp* op)
+{
+  startElement("isnan");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const TruncOp* op)
+{
+  startElement("trunc");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const RoundOp* op)
+{
+  startElement("round");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const FloorOp* op)
+{
+  startElement("floor");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const CeilingOp* op)
+{
+  startElement("ceiling");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const LogEOp* op)
+{
+  startElement("loge");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const Log2Op* op)
+{
+  startElement("log2");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const Log10Op* op)
+{
+  startElement("log10");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const SquareRootOp* op)
+{
+  startElement("squareroot");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const CubeRootOp* op)
+{
+  startElement("cuberoot");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const FactorialOp* op)
+{
+  startElement("factorial");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const PowerOp* op)
+{
+  startElement("power");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const RootOp* op)
+{
+  startElement("root");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const GCDOp* op)
+{
+  startElement("GCD");
+  putDoc(op);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const LCMOp* op)
+{
+  startElement("LCM");
+  putDoc(op);
+}
+
+template<> void
 XMLWriterImpl::WriterPass::put(const SelectOp* op)
 {
   startElement("select");
@@ -1000,10 +1115,10 @@
 }
 
 template<> void 
-XMLWriterImpl::WriterPass::put(const ReferenceOp* r)
+XMLWriterImpl::WriterPass::put(const GetOp* r)
 {
-  startElement("ref");
-  const Value* ref = r->getReferent();
+  startElement("get");
+  const Documentable* ref = r->getReferent();
   std::string name;
   if (isa<AutoVarOp>(ref))
     name = cast<AutoVarOp>(ref)->getName();
@@ -1011,6 +1126,8 @@
     name = cast<Argument>(ref)->getName();
   else if (isa<Constant>(ref))
     name = cast<Constant>(ref)->getName();
+  else if (isa<Type>(ref))
+    name = cast<Type>(ref)->getName();
   else
     name = "oops";
   writeAttribute("id",name);
@@ -1039,6 +1156,13 @@
 }
 
 template<> void 
+XMLWriterImpl::WriterPass::put(const ConvertOp* r)
+{
+  startElement("convert");
+  putDoc(r);
+}
+
+template<> void 
 XMLWriterImpl::WriterPass::put(const Bundle* b)
 {
   startElement("bundle");
@@ -1135,10 +1259,28 @@
       case GetFieldOpID:           put(cast<GetFieldOp>(n)); break;
       case GetIndexOpID:           put(cast<GetIndexOp>(n)); break;
       case LoadOpID:               put(cast<LoadOp>(n)); break;
-      case ReferenceOpID:          put(cast<ReferenceOp>(n)); break;
+      case GetOpID:                put(cast<GetOp>(n)); break;
       case OpenOpID:               put(cast<OpenOp>(n)); break;
       case CloseOpID:              put(cast<CloseOp>(n)); break;
       case WriteOpID:              put(cast<WriteOp>(n)); break;
+      case ConvertOpID:            put(cast<ConvertOp>(n)); break;
+      case IsPInfOpID:             put(cast<IsPInfOp>(n)); break;
+      case IsNInfOpID:             put(cast<IsNInfOp>(n)); break;
+      case IsNanOpID:              put(cast<IsNanOp>(n)); break;
+      case TruncOpID:              put(cast<TruncOp>(n)); break;
+      case RoundOpID:              put(cast<RoundOp>(n)); break;
+      case FloorOpID:              put(cast<FloorOp>(n)); break;
+      case CeilingOpID:            put(cast<CeilingOp>(n)); break;
+      case LogEOpID:               put(cast<LogEOp>(n)); break;
+      case Log2OpID:               put(cast<Log2Op>(n)); break;
+      case Log10OpID:              put(cast<Log10Op>(n)); break;
+      case SquareRootOpID:         put(cast<SquareRootOp>(n)); break;
+      case CubeRootOpID:           put(cast<CubeRootOp>(n)); break;
+      case FactorialOpID:          put(cast<FactorialOp>(n)); break;
+      case PowerOpID:              put(cast<PowerOp>(n)); break;
+      case RootOpID:               put(cast<RootOp>(n)); break;
+      case GCDOpID:                put(cast<GCDOp>(n)); break;
+      case LCMOpID:                put(cast<LCMOp>(n)); break;
       default:
         hlvmDeadCode("Unknown Type");
         break;
@@ -1191,8 +1333,9 @@
 {
   if (!node)
     return;
-  pass.handle(node,Pass::PreOrderTraversal);
-  pass.handle(node,Pass::PostOrderTraversal);
+  PassManager* PM = PassManager::create();
+  PM->addPass(&pass);
+  PM->runOnNode(node);
 }
 #endif
 

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

==============================================================================
--- hlvm/trunk/test/return0/arithmetic.hlx (original)
+++ hlvm/trunk/test/return0/arithmetic.hlx Sat Jul  7 19:03:00 2007
@@ -13,14 +13,14 @@
             <add>
               <mul>
                 <div>
-                  <ref id="42"/>
-                  <ref id="7"/>
+                  <get id="42"/>
+                  <get id="7"/>
                 </div>
-                <ref id="1"/>
+                <get id="1"/>
               </mul>
-              <ref id="2"/>
+              <get id="2"/>
             </add>
-            <ref id="8"/>
+            <get id="8"/>
           </sub>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/return0/bitwise.hlx (original)
+++ hlvm/trunk/test/return0/bitwise.hlx Sat Jul  7 19:03:00 2007
@@ -12,14 +12,14 @@
             <bnor>
               <bor>
                 <bxor>
-                  <ref id="0f0f0f0f"/>
-                  <ref id="08080808"/>
+                  <get id="0f0f0f0f"/>
+                  <get id="08080808"/>
                 </bxor>
-                <ref id="04040404"/>
+                <get id="04040404"/>
               </bor>
-              <ref id="0f0f0f0f"/>
+              <get id="0f0f0f0f"/>
             </bnor>
-            <ref id="00000000"/>
+            <get id="00000000"/>
           </band>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/return0/boolean.hlx (original)
+++ hlvm/trunk/test/return0/boolean.hlx Sat Jul  7 19:03:00 2007
@@ -13,17 +13,17 @@
               <nor>
                 <or>
                   <xor>
-                    <ref id="true"/>
-                    <ref id="false"/>
+                    <get id="true"/>
+                    <get id="false"/>
                   </xor>
-                  <ref id="false"/>
+                  <get id="false"/>
                 </or>
-                <ref id="true"/>
+                <get id="true"/>
               </nor>
-              <ref id="false"/>
+              <get id="false"/>
             </and>
-            <ref id="one"/>
-            <ref id="zero"/>
+            <get id="one"/>
+            <get id="zero"/>
           </select>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/return0/break.hlx (original)
+++ hlvm/trunk/test/return0/break.hlx Sat Jul  7 19:03:00 2007
@@ -11,14 +11,14 @@
       <block>
         <result>
           <while>
-            <ne><ref id="1"/><ref id="0"/></ne>
+            <ne><get id="1"/><get id="0"/></ne>
             <block>
               <select>
-                <ne><ref id="1"/><ref id="0"/></ne>
+                <ne><get id="1"/><get id="0"/></ne>
                 <block><break/></block>
-                <ref id="1"/>
+                <get id="1"/>
               </select>
-              <result><ref id="1"/></result>
+              <result><get id="1"/></result>
             </block>
           </while>
         </result>

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

==============================================================================
--- hlvm/trunk/test/return0/call.hlx (original)
+++ hlvm/trunk/test/return0/call.hlx Sat Jul  7 19:03:00 2007
@@ -6,7 +6,7 @@
     <function id="getResult" type="zero_func">
       <block>
         <result>
-          <ref id="zero"/>
+          <get id="zero"/>
         </result>
         <ret/>
       </block>
@@ -16,7 +16,7 @@
       <block>
         <result>
           <call>
-            <ref id="getResult"/>
+            <get id="getResult"/>
           </call>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/return0/complement.hlx (original)
+++ hlvm/trunk/test/return0/complement.hlx Sat Jul  7 19:03:00 2007
@@ -8,7 +8,7 @@
           <cmpl>
             <cmpl>
               <load>
-                <ref id="v"/>
+                <get id="v"/>
               </load>
             </cmpl>
           </cmpl>

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

==============================================================================
--- hlvm/trunk/test/return0/continue.hlx (original)
+++ hlvm/trunk/test/return0/continue.hlx Sat Jul  7 19:03:00 2007
@@ -9,17 +9,17 @@
         <autovar id="count" type="s32" init="10"/>
         <result>
           <while>
-            <ne><ref id="1"/><ref id="0"/></ne>
+            <ne><get id="1"/><get id="0"/></ne>
             <block>
               <select>
-                <gt><load><ref id="count"/></load><ref id="0"/></gt>
+                <gt><load><get id="count"/></load><get id="0"/></gt>
                 <block>
-                  <postdec><ref id="count"/></postdec>
+                  <postdec><get id="count"/></postdec>
                   <continue/>
                 </block>
                 <break/>
               </select>
-              <result><ref id="1"/></result>
+              <result><get id="1"/></result>
             </block>
           </while>
         </result>

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

==============================================================================
--- hlvm/trunk/test/return0/helloworld.hlx (original)
+++ hlvm/trunk/test/return0/helloworld.hlx Sat Jul  7 19:03:00 2007
@@ -15,18 +15,18 @@
       <block>
         <autovar id="out" type="stream"></autovar>
         <store>
-          <ref id="out"/>
-          <open><ref id="stdout"/></open>
+          <get id="out"/>
+          <open><get id="stdout"/></open>
         </store>
         <write>
-          <load><ref id="out"/></load>
-          <ref id="hw"/>
+          <load><get id="out"/></load>
+          <get id="hw"/>
         </write>
         <close>
-          <load><ref id="out"/></load>
+          <load><get id="out"/></load>
         </close>
         <result>
-          <ref id="zero"/>
+          <get id="zero"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/return0/loop.hlx (original)
+++ hlvm/trunk/test/return0/loop.hlx Sat Jul  7 19:03:00 2007
@@ -12,13 +12,13 @@
         <result>
           <loop>
             <ne>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </ne>
-            <block><result><ref id="0"/></result></block>
+            <block><result><get id="0"/></result></block>
             <eq>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </eq>
           </loop>
         </result>

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

==============================================================================
--- hlvm/trunk/test/return0/noresult.hlx (original)
+++ hlvm/trunk/test/return0/noresult.hlx Sat Jul  7 19:03:00 2007
@@ -11,14 +11,14 @@
       <block>
         <select>
           <ne>
-            <ref id="1"/>
-            <ref id="0"/>
+            <get id="1"/>
+            <get id="0"/>
           </ne>
-          <block><ref id="0"/></block>
-          <block><ref id="1"/></block>
+          <block><get id="0"/></block>
+          <block><get id="1"/></block>
         </select>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/return0/resultoverride.hlx (original)
+++ hlvm/trunk/test/return0/resultoverride.hlx Sat Jul  7 19:03:00 2007
@@ -6,10 +6,10 @@
     <program id="resultoverride">
       <block>
         <result>
-          <ref id="1"/>
+          <get id="1"/>
         </result>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/return0/return0.hlx (original)
+++ hlvm/trunk/test/return0/return0.hlx Sat Jul  7 19:03:00 2007
@@ -5,7 +5,7 @@
     <program id="return0">
       <block>
         <result>
-          <ref id="zero"/>
+          <get id="zero"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/return0/select.hlx (original)
+++ hlvm/trunk/test/return0/select.hlx Sat Jul  7 19:03:00 2007
@@ -13,17 +13,17 @@
             <block>
               <result>
                 <select>
-                  <ne><ref id="42"/><ref id="21"/></ne>
-                  <ref id="true"/>
-                  <ref id="false"/>
+                  <ne><get id="42"/><get id="21"/></ne>
+                  <get id="true"/>
+                  <get id="false"/>
                 </select>
               </result>
             </block>
             <block>
-              <result><ref id="0"/></result>
+              <result><get id="0"/></result>
             </block>
             <block>
-              <result><ref id="42"/></result>
+              <result><get id="42"/></result>
             </block>
           </select>
         </result>

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

==============================================================================
--- hlvm/trunk/test/return0/unless.hlx (original)
+++ hlvm/trunk/test/return0/unless.hlx Sat Jul  7 19:03:00 2007
@@ -12,10 +12,10 @@
         <result>
           <unless>
             <ne>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </ne>
-            <block><result><ref id="0"/></result></block>
+            <block><result><get id="0"/></result></block>
           </unless>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/return0/until.hlx (original)
+++ hlvm/trunk/test/return0/until.hlx Sat Jul  7 19:03:00 2007
@@ -11,10 +11,10 @@
       <block>
         <result>
           <until>
-            <block><result><ref id="0"/></result></block>
+            <block><result><get id="0"/></result></block>
             <ne>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </ne>
           </until>
         </result>

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

==============================================================================
--- hlvm/trunk/test/return0/unused.hlx (original)
+++ hlvm/trunk/test/return0/unused.hlx Sat Jul  7 19:03:00 2007
@@ -11,14 +11,14 @@
       <block>
         <select>
           <ne>
-            <ref id="1"/>
-            <ref id="0"/>
+            <get id="1"/>
+            <get id="0"/>
           </ne>
-          <block><result><ref id="0"/></result></block>
-          <block><result><ref id="1"/></result></block>
+          <block><result><get id="0"/></result></block>
+          <block><result><get id="1"/></result></block>
         </select>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/return0/while.hlx (original)
+++ hlvm/trunk/test/return0/while.hlx Sat Jul  7 19:03:00 2007
@@ -12,10 +12,10 @@
         <result>
           <while>
             <eq>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </eq>
-            <block><result><ref id="0"/></result></block>
+            <block><result><get id="0"/></result></block>
           </while>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/argscall.hlx (original)
+++ hlvm/trunk/test/xml2xml/argscall.hlx Sat Jul  7 19:03:00 2007
@@ -26,25 +26,25 @@
     <program id="argscall">
       <block>
         <call>
-          <ref id="none"/>
+          <get id="none"/>
         </call>
         <call>
-          <ref id="one"/>
-          <ref id="answer"/>
+          <get id="one"/>
+          <get id="answer"/>
         </call>
         <call>
-          <ref id="two"/>
-          <ref id="answer"/>
-          <ref id="answer"/>
+          <get id="two"/>
+          <get id="answer"/>
+          <get id="answer"/>
         </call>
         <call>
-          <ref id="va"/>
-          <ref id="answer"/>
-          <ref id="answer"/>
-          <ref id="answer"/>
+          <get id="va"/>
+          <get id="answer"/>
+          <get id="answer"/>
+          <get id="answer"/>
         </call>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/arithmetic.hlx (original)
+++ hlvm/trunk/test/xml2xml/arithmetic.hlx Sat Jul  7 19:03:00 2007
@@ -12,97 +12,97 @@
         <autovar id="v1" type="u32"/>
         <autovar id="v2" type="u32"/>
         <preinc>
-          <ref id="v1"/>
+          <get id="v1"/>
         </preinc>
         <postinc>
-          <ref id="v1"/>
+          <get id="v1"/>
         </postinc>
         <postdec>
-          <ref id="v2"/>
+          <get id="v2"/>
         </postdec>
         <predec>
-          <ref id="v2"/>
+          <get id="v2"/>
         </predec>
         <neg>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
         </neg>
         <cmpl>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </cmpl>
         <add>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
-          <ref id="one"/>
+          <get id="one"/>
         </add>
         <sub>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
-          <ref id="one"/>
+          <get id="one"/>
         </sub>
         <mul>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </mul>
         <div>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </div>
         <mod>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </mod>
         <band>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </band>
         <bor>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </bor>
         <bxor>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </bxor>
         <bnor>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </bnor>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/autovar.hlx (original)
+++ hlvm/trunk/test/xml2xml/autovar.hlx Sat Jul  7 19:03:00 2007
@@ -6,7 +6,7 @@
         <autovar id="v1" type="s32"/>
         <result>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/block.hlx (original)
+++ hlvm/trunk/test/xml2xml/block.hlx Sat Jul  7 19:03:00 2007
@@ -17,19 +17,19 @@
             <block>
               <result>
                 <ne>
-                  <ref id="0"/>
-                  <ref id="21"/>
+                  <get id="0"/>
+                  <get id="21"/>
                 </ne>
               </result>
             </block>
             <block>
               <result>
-                <ref id="42"/>
+                <get id="42"/>
               </result>
             </block>
             <block>
               <result>
-                <ref id="21"/>
+                <get id="21"/>
               </result>
             </block>
           </select>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/booleanops.hlx (original)
+++ hlvm/trunk/test/xml2xml/booleanops.hlx Sat Jul  7 19:03:00 2007
@@ -16,91 +16,91 @@
         <autovar id="v2" type="bool" init="false"/>
         <not>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
         </not>
         <and>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </and>
         <or>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </or>
         <nor>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </nor>
         <xor>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </xor>
         <eq>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </eq>
         <ne>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </ne>
         <gt>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </gt>
         <lt>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </lt>
         <ge>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </ge>
         <le>
           <load>
-            <ref id="v1"/>
+            <get id="v1"/>
           </load>
           <load>
-            <ref id="v2"/>
+            <get id="v2"/>
           </load>
         </le>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/break.hlx (original)
+++ hlvm/trunk/test/xml2xml/break.hlx Sat Jul  7 19:03:00 2007
@@ -10,14 +10,14 @@
     <program id="return">
       <block>
         <loop>
-          <ref id="true"/>
+          <get id="true"/>
           <block>
             <break/>
           </block>
-          <ref id="true"/>
+          <get id="true"/>
         </loop>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/call.hlx (original)
+++ hlvm/trunk/test/xml2xml/call.hlx Sat Jul  7 19:03:00 2007
@@ -9,10 +9,10 @@
     <program id="return">
       <block>
         <call>
-          <ref id="callee"/>
+          <get id="callee"/>
         </call>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/continue.hlx (original)
+++ hlvm/trunk/test/xml2xml/continue.hlx Sat Jul  7 19:03:00 2007
@@ -10,14 +10,14 @@
     <program id="return">
       <block>
         <loop>
-          <ref id="true"/>
+          <get id="true"/>
           <block>
             <continue/>
           </block>
-          <ref id="true"/>
+          <get id="true"/>
         </loop>
         <result>
-          <ref id="result"/>
+          <get id="result"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/doc.hlx (original)
+++ hlvm/trunk/test/xml2xml/doc.hlx Sat Jul  7 19:03:00 2007
@@ -79,7 +79,7 @@
       <block>
         <doc><i>This block just returns a constant result</i></doc>
         <result>
-          <ref id="s32val">
+          <get id="s32val">
             <doc>
               <b>This just references the intval constant as the result</b>
             </doc>
@@ -95,7 +95,7 @@
       <block>
         <doc>Again, doesn't do much but return a result</doc>
         <result>
-          <ref id="intval">
+          <get id="intval">
             <doc>
               <b>This just references the intval constant as the result</b>
             </doc>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/helloworld.hlx (original)
+++ hlvm/trunk/test/xml2xml/helloworld.hlx Sat Jul  7 19:03:00 2007
@@ -14,24 +14,24 @@
       <block>
         <autovar id="out" type="stream"/>
         <store>
-          <ref id="out"/>
+          <get id="out"/>
           <open>
-            <ref id="stdout"/>
+            <get id="stdout"/>
           </open>
         </store>
         <write>
           <load>
-            <ref id="out"/>
+            <get id="out"/>
           </load>
-          <ref id="hw"/>
+          <get id="hw"/>
         </write>
         <close>
           <load>
-            <ref id="out"/>
+            <get id="out"/>
           </load>
         </close>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/loop.hlx (original)
+++ hlvm/trunk/test/xml2xml/loop.hlx Sat Jul  7 19:03:00 2007
@@ -15,11 +15,11 @@
         <result>
           <loop>
             <ne>
-              <ref id="1"/>
-              <ref id="0"/>
+              <get id="1"/>
+              <get id="0"/>
             </ne>
-            <ref id="0"/>
-            <ref id="true"/>
+            <get id="0"/>
+            <get id="true"/>
           </loop>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/progargs.hlx (original)
+++ hlvm/trunk/test/xml2xml/progargs.hlx Sat Jul  7 19:03:00 2007
@@ -4,7 +4,7 @@
     <program id="progargs">
       <block>
         <result>
-          <ref id="argc"/>
+          <get id="argc"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/return.hlx (original)
+++ hlvm/trunk/test/xml2xml/return.hlx Sat Jul  7 19:03:00 2007
@@ -7,7 +7,7 @@
     <program id="return">
       <block>
         <result>
-          <ref id="42"/>
+          <get id="42"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/select.hlx (original)
+++ hlvm/trunk/test/xml2xml/select.hlx Sat Jul  7 19:03:00 2007
@@ -15,11 +15,11 @@
         <result>
           <select>
             <ne>
-              <ref id="0"/>
-              <ref id="21"/>
+              <get id="0"/>
+              <get id="21"/>
             </ne>
-            <ref id="42"/>
-            <ref id="21"/>
+            <get id="42"/>
+            <get id="21"/>
           </select>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/switch.hlx (original)
+++ hlvm/trunk/test/xml2xml/switch.hlx Sat Jul  7 19:03:00 2007
@@ -29,20 +29,20 @@
       <block>
         <result>
           <switch>
-            <ref id="42"/>
-            <ref id="42"/>
-            <ref id="1"/>
-            <ref id="1"/>
-            <ref id="2"/>
-            <ref id="2"/>
-            <ref id="3"/>
-            <ref id="3"/>
-            <ref id="4"/>
-            <ref id="4"/>
-            <ref id="5"/>
-            <ref id="5"/>
-            <ref id="42"/>
-            <ref id="21"/>
+            <get id="42"/>
+            <get id="42"/>
+            <get id="1"/>
+            <get id="1"/>
+            <get id="2"/>
+            <get id="2"/>
+            <get id="3"/>
+            <get id="3"/>
+            <get id="4"/>
+            <get id="4"/>
+            <get id="5"/>
+            <get id="5"/>
+            <get id="42"/>
+            <get id="21"/>
           </switch>
         </result>
         <ret/>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/unless.hlx (original)
+++ hlvm/trunk/test/xml2xml/unless.hlx Sat Jul  7 19:03:00 2007
@@ -11,13 +11,13 @@
       <block>
         <unless>
           <ne>
-            <ref id="1"/>
-            <ref id="0"/>
+            <get id="1"/>
+            <get id="0"/>
           </ne>
-          <ref id="0"/>
+          <get id="0"/>
         </unless>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/until.hlx (original)
+++ hlvm/trunk/test/xml2xml/until.hlx Sat Jul  7 19:03:00 2007
@@ -10,14 +10,14 @@
     <program id="until">
       <block>
         <until>
-          <ref id="0"/>
+          <get id="0"/>
           <ne>
-            <ref id="1"/>
-            <ref id="0"/>
+            <get id="1"/>
+            <get id="0"/>
           </ne>
         </until>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

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

==============================================================================
--- hlvm/trunk/test/xml2xml/while.hlx (original)
+++ hlvm/trunk/test/xml2xml/while.hlx Sat Jul  7 19:03:00 2007
@@ -11,13 +11,13 @@
       <block>
         <while>
           <ne>
-            <ref id="1"/>
-            <ref id="0"/>
+            <get id="1"/>
+            <get id="0"/>
           </ne>
-          <ref id="0"/>
+          <get id="0"/>
         </while>
         <result>
-          <ref id="0"/>
+          <get id="0"/>
         </result>
         <ret/>
       </block>

Modified: hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp?rev=38401&r1=38400&r2=38401&view=diff

==============================================================================
--- hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp (original)
+++ hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp Sat Jul  7 19:03:00 2007
@@ -46,41 +46,39 @@
 using namespace llvm;
 using namespace hlvm;
 
-namespace 
-{
-
-cl::opt<unsigned>
+static cl::opt<unsigned>
   Complexity("complexity", 
     cl::init(5),
     cl::desc("Specify complexity of generated code"), 
     cl::value_desc("num"));
 
-cl::opt<unsigned>
+static cl::opt<unsigned>
   TypeComplexity("type-complexity", 
     cl::init(4),
     cl::desc("Specify type complexity of generated code"), 
     cl::value_desc("num"));
 
-cl::opt<unsigned>
+static cl::opt<unsigned>
   Seed("seed", 
     cl::init(unsigned(time(0))), 
     cl::desc("Specify random number generator seed"), 
     cl::value_desc("num"));
 
-cl::opt<unsigned>
+static cl::opt<unsigned>
   Size("size",cl::desc("Specify size of generated code"),
       cl::value_desc("num"));
 
-AST* ast = 0;
-URI* uri = 0;
-Bundle* bundle = 0;
-Program* program = 0;
-unsigned line = 0;
 typedef std::vector<Value*> ValueList;
 typedef std::map<const Type*,ValueList> TypeValueMap;
-TypeValueMap values;
 typedef std::vector<Type*> TypeList;
-TypeList types;
+
+static AST* ast = 0;
+static URI* uri = 0;
+static Bundle* bundle = 0;
+static Program* program = 0;
+static unsigned line = 0;
+static TypeValueMap values;
+static TypeList types;
 
 inline Locator* 
 getLocator()
@@ -110,7 +108,7 @@
     return low;
 }
 
-Type*
+static Type*
 genType(unsigned limit)
 {
   Type* result = 0;
@@ -201,7 +199,7 @@
       Locator* loc = getLocator();
       std::string name = "array_" + utostr(line);
       result = ast->new_ArrayType(name,bundle,
-          genType(limit),randRange(1,Size),loc);
+          genType(limit),randRange(1,Size*10),loc);
       break;
     }
     case VectorTypeID:
@@ -209,7 +207,7 @@
       Locator* loc = getLocator();
       std::string name = "vector_" + utostr(line);
       result = ast->new_VectorType(name,bundle,
-          genType(limit),randRange(1,Size),loc);
+          genType(limit),randRange(1,Size*10),loc);
       break;
     }
     case OpaqueTypeID:
@@ -236,7 +234,7 @@
   return result;
 }
 
-Type*
+static Type*
 genType()
 {
   bool shouldGenNewType = randRange(0,5) < TypeComplexity;
@@ -248,7 +246,42 @@
   return types[ randRange(0,types.size()-1) ];
 }
 
-Value*
+static ConstantString*
+getConstantString(const std::string& str)
+{
+  typedef std::map<std::string,ConstantString*> strmap;
+  static strmap stringmap;
+  strmap::iterator I = stringmap.find(str);
+  if (I == stringmap.end()) {
+    Locator* loc = getLocator();
+    Type* Ty = bundle->getIntrinsicType(stringTy);
+    ConstantString* cstr = ast->new_ConstantString(
+      std::string("cstr_")+utostr(line),bundle,Ty,str,loc);
+    stringmap[str] = cstr;
+    return cstr;
+  }
+  return I->second;
+}
+
+static ConstantInteger*
+getConstantInteger(int32_t val)
+{
+  typedef std::map<int32_t,ConstantInteger*> intmap;
+  static intmap integermap;
+  intmap::iterator I = integermap.find(val);
+  if (I == integermap.end()) {
+    Locator* loc = getLocator();
+    Type* Ty = bundle->getIntrinsicType(intTy);
+    std::string val_str = itostr(val);
+    ConstantInteger* cint = ast->new_ConstantInteger(
+      std::string("cint_")+utostr(line),bundle,Ty,val_str,10,loc);
+    integermap[val] = cint;
+    return cint;
+  }
+  return I->second;
+}
+
+static Value*
 genValue(const Type* Ty, bool is_constant = false)
 {
   if (!is_constant && randRange(0,Complexity) < Complexity/2) {
@@ -299,8 +332,7 @@
       unsigned numChars = randRange(1,Size+Complexity,true);
       for (unsigned i = 0 ; i < numChars; i++)
         val += char(randRange(35,126));
-      C = ast->new_ConstantString(
-        std::string("cstr_")+utostr(line),bundle,Ty,val,loc);
+      C = getConstantString(val);
       break;
     }
     case BufferTypeID:
@@ -433,49 +465,530 @@
   return result;
 }
 
-inline Operator*
-genValueOperator(const Type *Ty, bool is_constant = false)
+static inline GetOp*
+getReference(const Value* val)
+{
+  hlvmAssert(isa<Linkable>(val) || isa<Constant>(val) || isa<AutoVarOp>(val));
+  return ast->new_GetOp(val,getLocator());
+}
+
+static inline Operator*
+genValueAsOperator(const Type *Ty, bool is_constant = false)
 {
   Value* V = genValue(Ty,is_constant);
-  Operator* O = ast->new_ReferenceOp(V,getLocator());
+  Operator* O = getReference(V);
   if (isa<Linkable>(V))
     O = ast->new_UnaryOp<LoadOp>(O,bundle,getLocator());
   return O;
 }
 
-
-CallOp*
+static CallOp*
 genCallTo(Function* F)
 {
   std::vector<Operator*> args;
-  Operator* O = ast->new_ReferenceOp(F,getLocator());
+  Operator* O = ast->new_GetOp(F,getLocator());
   args.push_back(O);
   const SignatureType* sig = F->getSignature();
   for (SignatureType::const_iterator I = sig->begin(), E = sig->end(); 
        I != E; ++I) 
   {
     const Type* argTy = (*I)->getType();
-    Operator* O = genValueOperator(argTy);
+    Operator* O = genValueAsOperator(argTy);
     hlvmAssert(argTy == O->getType());
     args.push_back(O);
   }
   return ast->new_MultiOp<CallOp>(args,bundle,getLocator());
 }
 
-Block*
-genBlock()
+static Operator*
+genIndex(Operator* V)
+{
+  if (V->typeis<StructureType>()) {
+    const StructureType* Ty = cast<StructureType>(V->getType());
+    const NamedType* fldname = Ty->getField(randRange(0,Ty->size()-1));
+    Constant* cfield = getConstantString(fldname->getName());
+    GetOp* field  = getReference(cfield);
+    return ast->new_BinaryOp<GetFieldOp>(V,field,bundle,getLocator());
+  } else if (V->typeis<ArrayType>()) {
+    const ArrayType* Ty = cast<ArrayType>(V->getType());
+    Constant* cindex = getConstantInteger(0); //FIXME: gen rand at runtime
+    GetOp* index = getReference(cindex);
+    return ast->new_BinaryOp<GetIndexOp>(V,index,bundle,getLocator());
+  } else if (V->typeis<VectorType>()) {
+    const VectorType* Ty = cast<VectorType>(V->getType());
+    int64_t idx = randRange(0,Ty->getSize()-1);
+    Constant* cindex = getConstantInteger(idx);
+    GetOp* index = getReference(cindex);
+    return ast->new_BinaryOp<GetIndexOp>(V,index,bundle,getLocator());
+  } else if (V->typeis<StringType>()) {
+    const StringType* Ty = cast<StringType>(V->getType());
+    Constant* cindex = getConstantInteger(0); //FIXME: gen rand at runtime
+    GetOp* index = getReference(cindex);
+    return ast->new_BinaryOp<GetIndexOp>(V,index,bundle,getLocator());
+  } else if (V->typeis<PointerType>()) {
+    Constant* cindex = getConstantInteger(0);
+    GetOp* index = getReference(cindex);
+    return ast->new_BinaryOp<GetIndexOp>(V,index,bundle,getLocator());
+  } else
+    hlvmAssert(!"Can't index this type!");
+  return 0;
+}
+
+static Operator*
+genBooleanUnary(Operator* V1) 
+{
+  hlvmAssert(V1->getType()->getID() == BooleanTypeID);
+  return ast->new_UnaryOp<NotOp>(V1,bundle,getLocator());
+}
+
+static Operator*
+genBooleanBinary(Operator* V1, Operator* V2) 
+{
+  hlvmAssert(V1->getType()->getID() == BooleanTypeID);
+  hlvmAssert(V2->getType()->getID() == BooleanTypeID);
+  Operator* result = 0;
+  NodeIDs id = NodeIDs(randRange(AndOpID,InequalityOpID));
+  switch (id) {
+    case AndOpID:
+      result = ast->new_BinaryOp<AndOp>(V1,V2,bundle,getLocator());
+      break;
+    case OrOpID:
+      result = ast->new_BinaryOp<OrOp>(V1,V2,bundle,getLocator());
+      break;
+    case NorOpID:
+      result = ast->new_BinaryOp<NorOp>(V1,V2,bundle,getLocator());
+      break;
+    case XorOpID:
+      result = ast->new_BinaryOp<XorOp>(V1,V2,bundle,getLocator());
+      break;
+    case LessThanOpID:
+      result = ast->new_BinaryOp<LessThanOp>(V1,V2,bundle,getLocator());
+      break;
+    case GreaterThanOpID:
+      result = ast->new_BinaryOp<GreaterThanOp>(V1,V2,bundle,getLocator());
+      break;
+    case LessEqualOpID:
+      result = ast->new_BinaryOp<LessEqualOp>(V1,V2,bundle,getLocator());
+      break;
+    case GreaterEqualOpID:
+      result = ast->new_BinaryOp<GreaterEqualOp>(V1,V2,bundle,getLocator());
+      break;
+    case EqualityOpID:
+      result = ast->new_BinaryOp<EqualityOp>(V1,V2,bundle,getLocator());
+      break;
+    case InequalityOpID:
+      result = ast->new_BinaryOp<InequalityOp>(V1,V2,bundle,getLocator());
+      break;
+    default:
+      hlvmAssert(!"Invalid boolean op ID");
+  }
+  return result;
+}
+
+static Operator*
+genCharacterUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == CharacterTypeID);
+  return 0;
+}
+
+static Operator*
+genCharacterBinary(Operator* V1, Operator* V2) 
+{
+  hlvmAssert(V1->getType()->getID() == CharacterTypeID);
+  hlvmAssert(V2->getType()->getID() == CharacterTypeID);
+  return 0;
+}
+
+static Operator*
+genIntegerUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == IntegerTypeID);
+  Operator* result = 0;
+  NodeIDs id = NodeIDs(randRange(NegateOpID, PostDecrOpID));
+  switch (id) {
+    case NegateOpID:
+      result = ast->new_UnaryOp<NegateOp>(V1,bundle,getLocator());
+      break;
+    case ComplementOpID:
+      result = ast->new_UnaryOp<ComplementOp>(V1,bundle,getLocator());
+      break;
+    case PreIncrOpID:
+      result = ast->new_UnaryOp<PreIncrOp>(V1,bundle,getLocator());
+      break;
+    case PostIncrOpID:
+      result = ast->new_UnaryOp<PostIncrOp>(V1,bundle,getLocator());
+      break;
+    case PreDecrOpID:
+      result = ast->new_UnaryOp<PreDecrOp>(V1,bundle,getLocator());
+      break;
+    case PostDecrOpID:
+      result = ast->new_UnaryOp<NegateOp>(V1,bundle,getLocator());
+      break;
+    default:
+      hlvmAssert(!"Invalid unary op id for integer");
+      result = ast->new_UnaryOp<ComplementOp>(V1,bundle,getLocator());
+  }
+  return result;
+}
+
+static Operator*
+genIntegerBinary(Operator* V1, Operator* V2)
+{
+  hlvmAssert(V1->getType()->getID() == IntegerTypeID);
+  hlvmAssert(V2->getType()->getID() == IntegerTypeID);
+  Operator* result = 0;
+  NodeIDs id = NodeIDs(randRange(AddOpID, BNorOpID));
+  switch (id) {
+    case AddOpID:
+      result = ast->new_BinaryOp<AddOp>(V1,V2,bundle,getLocator());
+      break;
+    case SubtractOpID:
+      result = ast->new_BinaryOp<SubtractOp>(V1,V2,bundle,getLocator());
+      break;
+    case MultiplyOpID:
+      result = ast->new_BinaryOp<MultiplyOp>(V1,V2,bundle,getLocator());
+      break;
+    case DivideOpID:
+      result = ast->new_BinaryOp<DivideOp>(V1,V2,bundle,getLocator());
+      break;
+    case ModuloOpID:
+      result = ast->new_BinaryOp<ModuloOp>(V1,V2,bundle,getLocator());
+      break;
+    case BAndOpID:
+      result = ast->new_BinaryOp<BAndOp>(V1,V2,bundle,getLocator());
+      break;
+    case BOrOpID:
+      result = ast->new_BinaryOp<BOrOp>(V1,V2,bundle,getLocator());
+      break;
+    case BXorOpID:
+      result = ast->new_BinaryOp<BXorOp>(V1,V2,bundle,getLocator());
+      break;
+    case BNorOpID:
+      result = ast->new_BinaryOp<BNorOp>(V1,V2,bundle,getLocator());
+      break;
+    default:
+      hlvmAssert(!"Invalid binary op id for integer");
+      result = ast->new_BinaryOp<AddOp>(V1,V2,bundle,getLocator());
+  }
+  return result;
+}
+
+static Operator*
+genRealUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  Operator* result = 0;
+  NodeIDs id = NodeIDs(randRange(TruncOpID,FactorialOpID));
+  switch (id) {
+    case TruncOpID:
+      result = ast->new_UnaryOp<TruncOp>(V1,bundle,getLocator());
+      break;
+    case RoundOpID:
+      result = ast->new_UnaryOp<RoundOp>(V1,bundle,getLocator());
+      break;
+    case FloorOpID:
+      result = ast->new_UnaryOp<FloorOp>(V1,bundle,getLocator());
+      break;
+    case CeilingOpID:
+      result = ast->new_UnaryOp<CeilingOp>(V1,bundle,getLocator());
+      break;
+    case LogEOpID:
+      result = ast->new_UnaryOp<LogEOp>(V1,bundle,getLocator());
+      break;
+    case Log2OpID:
+      result = ast->new_UnaryOp<Log2Op>(V1,bundle,getLocator());
+      break;
+    case Log10OpID:
+      result = ast->new_UnaryOp<Log10Op>(V1,bundle,getLocator());
+      break;
+    case SquareRootOpID:
+      result = ast->new_UnaryOp<SquareRootOp>(V1,bundle,getLocator());
+      break;
+    case CubeRootOpID:
+      result = ast->new_UnaryOp<CubeRootOp>(V1,bundle,getLocator());
+      break;
+    case FactorialOpID:
+      result = ast->new_UnaryOp<FactorialOp>(V1,bundle,getLocator());
+      break;
+    default:
+      hlvmAssert(!"Invalid unary op id for integer");
+      result = ast->new_UnaryOp<CeilingOp>(V1,bundle,getLocator());
+  }
+  return result;
+}
+
+static Operator*
+genRealBinary(Operator* V1, Operator* V2)
 {
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  hlvmAssert(V2->getType()->getID() == RealTypeID);
+  Operator* result = 0;
+  NodeIDs id = hlvm::NodeIDs(randRange(PowerOpID, LCMOpID));
+  switch (id) {
+    case PowerOpID:
+      result = ast->new_BinaryOp<PowerOp>(V1,V2,bundle,getLocator());
+      break;
+    case RootOpID:
+      result = ast->new_BinaryOp<RootOp>(V1,V2,bundle,getLocator());
+      break;
+    case GCDOpID:
+      result = ast->new_BinaryOp<GCDOp>(V1,V2,bundle,getLocator());
+      break;
+    case LCMOpID:
+      result = ast->new_BinaryOp<LCMOp>(V1,V2,bundle,getLocator());
+      break;
+    default:
+      hlvmAssert(!"Invalid binary op id for integer");
+      result = ast->new_BinaryOp<PowerOp>(V1,V2,bundle,getLocator());
+  }
+  return result;
+}
+
+static Operator*
+genStringUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  return 0;
+}
+
+static Operator*
+genStringBinary(Operator* V1, Operator* V2)
+{
+  return 0;
+}
+
+static Operator*
+genPointerUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  return 0;
+}
+
+static Operator*
+genPointerBinary(Operator* V1, Operator* V2)
+{
+  return 0;
+}
+
+static Operator*
+genArrayUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  return 0;
+}
+
+static Operator*
+genArrayBinary(Operator* V1, Operator* V2)
+{
+  return 0;
+}
+
+static Operator*
+genVectorUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  return 0;
+}
+
+static Operator*
+genVectorBinary(Operator* V1, Operator* V2)
+{
+  return 0;
+}
+
+static Operator*
+genStructureUnary(Operator* V1)
+{
+  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  return 0;
+}
+
+static Operator*
+genStructureBinary(Operator* V1, Operator* V2)
+{
+  return 0;
+}
+
+// Forward declare
+static Function* genFunction(const Type* resultType, unsigned depth);
+
+static Operator*
+genExpression(Operator* Val, const Type* Ty, unsigned depth)
+{
+  hlvmAssert(Val->getType() == Ty);
+  if (depth > 0) {
+    // Generate a function
+    Function* F = genFunction(Ty, depth-1);
+    // Generate a call to that function
+    return genCallTo(F);
+  }
+
+  Operator* result = 0;
+
+  // Determine whether to generate a binary or unary expression
+  if (5 <= randRange(1,10)) {
+    switch (Ty->getID()) {
+      case BooleanTypeID: result = genBooleanUnary(Val); break;
+      case CharacterTypeID: result = genCharacterUnary(Val); break;
+      case AnyTypeID:         
+      case BufferTypeID:
+      case StreamTypeID:
+      case TextTypeID:
+      case SignatureTypeID:
+      case RationalTypeID:
+        // FALL THROUGH: Not Implemented
+      case RangeTypeID:
+      case IntegerTypeID:
+      case EnumerationTypeID: result = genIntegerUnary(Val); break;
+      case RealTypeID: result = genRealUnary(Val); break;
+      case StringTypeID: result = genStringUnary(Val); break;
+      case PointerTypeID: result = genPointerUnary(Val); break;
+      case ArrayTypeID: result = genArrayUnary(Val); break;
+      case VectorTypeID: result = genVectorUnary(Val); break;
+      case OpaqueTypeID:
+      case ContinuationTypeID:
+      case StructureTypeID: result = genStructureUnary(Val); break;
+      default:
+        hlvmAssert(!"Invalid type?");
+        break;
+    }
+  } else {
+    switch (Ty->getID()) {
+      case BooleanTypeID: 
+        result = genBooleanBinary(Val,genValueAsOperator(Ty)); break;
+      case CharacterTypeID:
+        result = genCharacterBinary(Val,genValueAsOperator(Ty)); break;
+      case AnyTypeID:         
+      case BufferTypeID:
+      case StreamTypeID:
+      case TextTypeID:
+      case SignatureTypeID:
+      case RationalTypeID:
+        // FALL THROUGH: Not Implemented
+      case RangeTypeID:
+      case IntegerTypeID:
+      case EnumerationTypeID: 
+        result = genIntegerBinary(Val,genValueAsOperator(Ty));break;
+      case RealTypeID: 
+        result = genRealBinary(Val,genValueAsOperator(Ty)); break;
+      case StringTypeID: 
+        result = genStringBinary(Val,genValueAsOperator(Ty)); break;
+      case PointerTypeID: 
+        result = genPointerBinary(Val,genValueAsOperator(Ty)); break;
+      case ArrayTypeID: 
+        result = genArrayBinary(Val,genValueAsOperator(Ty)); break;
+      case VectorTypeID: 
+        result = genVectorBinary(Val,genValueAsOperator(Ty)); break;
+      case OpaqueTypeID:
+      case ContinuationTypeID:
+      case StructureTypeID: 
+        result = genStructureBinary(Val,genValueAsOperator(Ty));break;
+      default:
+        hlvmAssert(!"Invalid type?");
+        break;
+    }
+  }
+  return result;
+}
+
+static void
+genMergeExpression(AutoVarOp* op1, Operator* op2, Block* B)
+{
+  // Assert precondition
+  hlvmAssert(op1->getType() == op2->getType());
+
+  // Get the type of the thing to be merged
+  const Type* Ty = op2->getType();
+
+
+  // If its just a numeric type, simply add the merged value into the autovar
+  if (Ty->isNumericType()) {
+    Operator* get1 = ast->new_GetOp(op1,getLocator());
+    Operator* avload = ast->new_UnaryOp<LoadOp>(get1,bundle,getLocator());
+    Operator* add = ast->new_BinaryOp<AddOp>(avload,op2,bundle,getLocator());
+    Operator* get2 = ast->new_GetOp(op1,getLocator());
+    Operator* store = ast->new_BinaryOp<StoreOp>(get2,add,bundle,getLocator());
+    store->setParent(B);
+    return;
+  }
+
+  // If its a VectorType or ArrayType then add all the elements, if possible
+  if (const UniformContainerType* UCT = 
+        llvm::dyn_cast<UniformContainerType>(op2->getType())) {
+    const Type* elemType = UCT->getElementType();
+    if (elemType->isNumericType()) {
+      Operator* get1 = ast->new_GetOp(op1,getLocator());
+      Operator* avload = ast->new_UnaryOp<LoadOp>(get1,bundle,getLocator());
+      Operator* add = ast->new_BinaryOp<AddOp>(avload,op2,bundle,getLocator());
+      Operator* get2 = ast->new_GetOp(op1,getLocator());
+      Operator* store =ast->new_BinaryOp<StoreOp>(get2,add,bundle,getLocator());
+      store->setParent(B);
+      return;
+    } 
+  }
+
+  // For everything else, just store the result
+  Operator* get = ast->new_GetOp(op1,getLocator());
+  Operator* op = ast->new_BinaryOp<StoreOp>(get,op2,bundle,getLocator());
+  op->setParent(B);
+  return;
+}
+
+static Block*
+genFunctionBody(Function* F, unsigned depth)
+{
+  // Create the function body block and initialize it
   Block* B = ast->new_Block(getLocator());
+  B->setParent(F);
+  B->setLabel(F->getName() + "_body");
+
+  // Create an autovar for the function result
+  AutoVarOp* result = 
+    ast->new_AutoVarOp(F->getName() + "_result",
+                       F->getResultType(),getLocator());
+  result->setParent(B);
+
+  // Generate "Size" expressions
+  for (unsigned i = 0; i < Size; i++) {
+    // Get a value for the basis of the expression
+    Operator* theValue = 0;
+    if (F->size() > 0) {
+      // Pick an argument randomly to use in the expression
+      unsigned argNum = randRange(0,F->size()-1);
+      Argument* arg = F->getArgument(argNum);
+      theValue = ast->new_GetOp(arg,getLocator());
+    } else {
+      theValue = genValueAsOperator(F->getResultType());
+    }
+
+    // Generate the expression
+    Operator* expr = genExpression(theValue,F->getResultType(),depth-1);
+
+    // Merge the current value of the autovar result with the generated
+    // expression.
+    genMergeExpression(result,expr,B);
+  }
+  
+  // Create the block result.
+  GetOp* get = ast->new_GetOp(result,getLocator());
+  ResultOp* rslt = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  rslt->setParent(B);
+
+  // Done, Return the new block
   return B;
 }
 
-Function*
-genFunction(Type* resultType, unsigned numArgs)
+static Function*
+genFunction(const Type* resultType, unsigned depth)
 {
   // Get the function name
   Locator* loc = getLocator();
   std::string name = "func_" + utostr(line);
 
+  // Generate a random number of arguments
+  unsigned numArgs = int(randRange(0,int(Complexity)));
+
   // Get the signature
   std::string sigName = name + "_type";
   SignatureType* sig = ast->new_SignatureType(sigName,bundle,resultType,loc);
@@ -484,67 +997,100 @@
   for (unsigned i = 0; i < numArgs; ++i )
   {
     std::string name = "arg_" + utostr(i+1);
-    Parameter* param = ast->new_Parameter(name,genType(),loc);
+    Parameter* param = ast->new_Parameter(name,resultType,loc);
     sig->addParameter(param);
   }
   sig->setParent(bundle);
 
-  // Create the function and set its linkage
+  // Determine the kind of linkage for this function
   LinkageKinds LK = LinkageKinds(randRange(ExternalLinkage,InternalLinkage));
   if (LK == AppendingLinkage)
     LK = InternalLinkage;
+
+  // Create the function and set its linkage kind
   Function* F = ast->new_Function(name,bundle,sig,loc);
   F->setLinkageKind(LK);
 
-  // Create a block and set its parent
-  Block* B = genBlock();
-  B->setParent(F);
-
-  // Get the function result and return instruction
-  Operator* O = genValueOperator(F->getResultType());
-  ResultOp* rslt = ast->new_UnaryOp<ResultOp>(O,bundle,getLocator());
-  rslt->setParent(B);
+  // Create the body of the function
+  Block* blk = genFunctionBody(F,depth);
 
+  // Insert the return operator
   ReturnOp* ret = ast->new_NilaryOp<ReturnOp>(bundle,getLocator());
-  ret->setParent(B);
+  ret->setParent(blk);
   
   // Install the function in the value map
   values[sig].push_back(F);
 
-  return F;
-}
+  // Make the function belong to the bundle
+  F->setParent(bundle);
 
+  return F;
 }
 
 AST* 
 GenerateTestCase(const std::string& pubid, const std::string& bundleName)
 {
+  // Seed the random number generator
   srandom(Seed);
+
+  // Create the top level node of the tree
   ast = AST::create();
   ast->setPublicID(pubid);
   ast->setSystemID(bundleName);
+
+  // Get a URI for this tree
   uri = ast->new_URI(pubid);
+  
+  // Create a bundle to place the program in.
   bundle = ast->new_Bundle(bundleName,getLocator());
+
+  // Create a program node for the generated test program
   program = ast->new_Program(bundleName,bundle,getLocator());
-  Block* blk = ast->new_Block(getLocator());
-  blk->setParent(program);
+  const SignatureType* SigTy = program->getSignature();
+
+  // Create the function body block and initialize it
+  Block* B = ast->new_Block(getLocator());
+  B->setParent(program);
+  B->setLabel(program->getName() + "_body");
+
+  // Create an autovar for the function result
+  AutoVarOp* result = 
+    ast->new_AutoVarOp(program->getName() + "_result",
+                       program->getResultType(),getLocator());
+  result->setParent(B);
+
+  // Generate calls to "Size" random functions
   for (unsigned i = 0; i < Size; i++) {
-    Type* result = genType();
-    Type* argTy  = genType();
-    unsigned numArgs = int(randRange(0,int(Complexity)));
-    Function* F = genFunction(result,numArgs);
-    F->setParent(bundle);
+    // Generate a function to a random type
+    Type* Ty = genType();
+    Function* F = genFunction(Ty, Complexity);
+
+    // Generate a call to that function
     CallOp* call = genCallTo(F);
-    call->setParent(blk);
-  }
 
-  // Get the function result and return instruction
-  Operator* O = genValueOperator(program->getResultType());
-  ResultOp* rslt = ast->new_UnaryOp<ResultOp>(O,bundle,getLocator());
-  rslt->setParent(blk);
+    // Coalesce the result of the random function into the autovar we
+    // created for the result of this block.
+    if (Ty->isNumericType()) {
+      Operator* get = 
+        ast->new_GetOp(program->getResultType(),getLocator());
+      Operator* cvt = 
+        ast->new_BinaryOp<ConvertOp>(call,get,bundle,getLocator());
+      genMergeExpression(result,cvt,B);
+    }
+  }
+  
+  // Create the block result.
+  GetOp* get = ast->new_GetOp(result,getLocator());
+  ResultOp* rslt = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  rslt->setParent(B);
 
+  // Insert the return instruction in that block
   ReturnOp* ret = ast->new_NilaryOp<ReturnOp>(bundle,getLocator());
-  ret->setParent(blk);
+  ret->setParent(B);
+
+  // Make the program a child of the bundle last so it is output last.
   program->setParent(bundle);
+
+  // Done.
   return ast;
 }





More information about the llvm-commits mailing list