[llvm-commits] [hlvm] r38294 - in /hlvm/trunk: hlvm/AST/Bundle.cpp hlvm/AST/Bundle.h hlvm/AST/ContainerType.h hlvm/CodeGen/LLVMGenerator.cpp hlvm/Pass/Pass.cpp hlvm/Pass/Validate.cpp test/error/argscall.hlx test/error/argtype.hlx test/xml2xml/argscall.hlx

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


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

URL: http://llvm.org/viewvc/llvm-project?rev=38294&view=rev
Log:
Implement argument passing to functions. It turns out that bundle
declaration order is important so we also added a vector to retain
order of declaration which is used by the Pass class when traversing
the tree.

Added:
    hlvm/trunk/test/error/argscall.hlx
    hlvm/trunk/test/error/argtype.hlx
    hlvm/trunk/test/xml2xml/argscall.hlx
Modified:
    hlvm/trunk/hlvm/AST/Bundle.cpp
    hlvm/trunk/hlvm/AST/Bundle.h
    hlvm/trunk/hlvm/AST/ContainerType.h
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/Pass/Pass.cpp
    hlvm/trunk/hlvm/Pass/Validate.cpp

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

==============================================================================
--- hlvm/trunk/hlvm/AST/Bundle.cpp (original)
+++ hlvm/trunk/hlvm/AST/Bundle.cpp Sat Jul  7 19:02:02 2007
@@ -45,11 +45,15 @@
   hlvmAssert(kid && "Null child!");
   if (isa<Type>(kid))
     types.insert(cast<Type>(kid)->getName(), cast<Type>(kid));
-  else if (isa<ConstantValue>(kid))
-    cvals.insert(cast<ConstantValue>(kid)->getName(), cast<ConstantValue>(kid));
-  else if (isa<Linkable>(kid))
-    linkables.insert(cast<Linkable>(kid)->getName(), cast<Linkable>(kid));
-  else
+  else if (isa<Value>(kid)) {
+    values.push_back(cast<Value>(kid));
+    if (isa<ConstantValue>(kid)) {
+      cvals.insert(cast<ConstantValue>(kid)->getName(), 
+                   cast<ConstantValue>(kid));
+    } else if (isa<Linkable>(kid)) {
+      linkables.insert(cast<Linkable>(kid)->getName(), cast<Linkable>(kid));
+    }
+  } else
     hlvmAssert("Don't know how to insert that in a Bundle");
 }
 
@@ -60,11 +64,14 @@
   // This is sucky slow, but we probably won't be removing nodes that much.
   if (isa<Type>(kid))
     types.erase(cast<Type>(kid)->getName());
-  else if (isa<ConstantValue>(kid))
-    cvals.erase(cast<ConstantValue>(kid)->getName());
-  else if (isa<Linkable>(kid))
-    linkables.erase(cast<Linkable>(kid)->getName());
-  else 
+  else if (isa<Value>(kid)) {
+    for (value_iterator I = value_begin(), E = value_end(); I != E; ++I )
+      if (*I == kid) { values.erase(I); break; }
+    if (isa<ConstantValue>(kid))
+      cvals.erase(cast<ConstantValue>(kid)->getName());
+    else if (isa<Linkable>(kid))
+      linkables.erase(cast<Linkable>(kid)->getName());
+  } else 
     hlvmAssert(!"That node isn't my child");
 }
 

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

==============================================================================
--- hlvm/trunk/hlvm/AST/Bundle.h (original)
+++ hlvm/trunk/hlvm/AST/Bundle.h Sat Jul  7 19:02:02 2007
@@ -58,6 +58,10 @@
     typedef TypeList::iterator type_iterator;
     typedef TypeList::const_iterator type_const_iterator;
 
+    typedef std::vector<Value*> ValueList;
+    typedef ValueList::iterator value_iterator;
+    typedef ValueList::const_iterator value_const_iterator;
+
     typedef SymbolTable<ConstantValue> CValList;
     typedef CValList::iterator cval_iterator;
     typedef CValList::const_iterator cval_const_iterator;
@@ -109,7 +113,16 @@
     size_t                  type_size () const { return types.size(); }
     bool                    type_empty() const { return types.empty(); }
 
-    /// Type iteration
+    /// Value Insertion Order Iteration
+    //
+    value_iterator          value_begin()       { return values.begin(); }
+    value_const_iterator    value_begin() const { return values.begin(); }
+    value_iterator          value_end  ()       { return values.end(); }
+    value_const_iterator    value_end  () const { return values.end(); }
+    size_t                  value_size () const { return values.size(); }
+    bool                    value_empty() const { return values.empty(); }
+
+    /// ConstantValue Symbol Table iteration
     cval_iterator           cval_begin()       { return cvals.begin(); }
     cval_const_iterator     cval_begin() const { return cvals.begin(); }
     cval_iterator           cval_end  ()       { return cvals.end(); }
@@ -117,7 +130,7 @@
     size_t                  cval_size () const { return cvals.size(); }
     bool                    cval_empty() const { return cvals.empty(); }
 
-    /// Value iteration
+    /// Linkable Symbol Table iteration
     linkable_iterator       linkable_begin()       { return linkables.begin(); }
     linkable_const_iterator linkable_begin() const { return linkables.begin(); }
     linkable_iterator       linkable_end  ()       { return linkables.end(); }
@@ -131,6 +144,7 @@
   protected:
     std::string  name;      ///< The name for this bundle
     TypeList     types;     ///< The list of types
+    ValueList    values;    ///< The list of values in insertion order
     CValList     cvals;     ///< The list of constant values
     LinkableList linkables; ///< The list of linkables
 

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

==============================================================================
--- hlvm/trunk/hlvm/AST/ContainerType.h (original)
+++ hlvm/trunk/hlvm/AST/ContainerType.h Sat Jul  7 19:02:02 2007
@@ -375,7 +375,7 @@
   /// @{
   protected:
     SignatureType() 
-      : DisparateContainerType(SignatureTypeID), result(0), varargs(false) {}
+      : DisparateContainerType(SignatureTypeID), result(0) {}
     virtual ~SignatureType();
 
   /// @}
@@ -383,7 +383,7 @@
   /// @{
   public:
     const Type* getResultType() const { return result; }
-    bool  isVarArgs() const { return varargs; }
+    bool  isVarArgs() const { return flags != 0; }
 
     /// Methods to support type inquiry via is, cast, dyn_cast
     static inline bool classof(const SignatureType*) { return true; }
@@ -395,7 +395,7 @@
   /// @{
   public:
     void setResultType(const Type* ty) { result = ty; }
-    void setIsVarArgs(bool is) { varargs = is; }
+    void setIsVarArgs(bool is) { flags = is ? 1 : 0; }
     void addArgument(Argument* arg) { contents.push_back(arg); }
 
   /// @}
@@ -403,7 +403,6 @@
   /// @{
   protected:
     const Type* result;  ///< The result type of the function signature
-    bool varargs;        ///< Indicates variable arguments function
   /// @}
   friend class AST;
 };

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

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:02:02 2007
@@ -69,6 +69,7 @@
 
 namespace 
 {
+
 using namespace hlvm;
 
 class LLVMGeneratorPass : public hlvm::Pass
@@ -77,7 +78,8 @@
   typedef std::vector<llvm::Value*> OperandList;
   typedef std::map<const hlvm::Variable*,llvm::Value*> VariableDictionary;
   typedef std::map<const hlvm::AutoVarOp*,llvm::Value*> AutoVarDictionary;
-  typedef std::map<const hlvm::ConstantValue*,llvm::Constant*> ConstantDictionary;
+  typedef std::map<const hlvm::ConstantValue*,llvm::Constant*> 
+    ConstantDictionary;
   typedef std::map<const hlvm::Function*,llvm::Function*> FunctionDictionary;
   ModuleList modules;        ///< The list of modules we construct
   llvm::Module*     lmod;    ///< The current module we're generation 
@@ -85,8 +87,8 @@
   llvm::BasicBlock* lblk;    ///< The current LLVM block we're generating
   llvm::BasicBlock::InstListType linst; 
   OperandList lops;          ///< The current list of instruction operands
-  VariableDictionary gvars;
-  AutoVarDictionary lvars;
+  VariableDictionary gvars;  ///< Dictionary of HLVM -> LLVM gvars
+  AutoVarDictionary lvars;   ///< Dictionary of HLVM -> LLVM auto vars
   llvm::TypeSymbolTable ltypes; ///< The cached LLVM types we've generated
   ConstantDictionary consts; ///< The cached LLVM constants we've generated
   FunctionDictionary funcs;  ///< The cached LLVM constants we've generated
@@ -1177,12 +1179,17 @@
   const SignatureType* sigTy = hFunc->getSignature();
   std::vector<llvm::Value*> args;
   hlvmAssert(lops.size() >= sigTy->size()+1 && "Too few operands for CallOp");
-  if (sigTy->size() > 0) {
-    for (unsigned i = sigTy->size()-1; i >= 0; i++)
-      args.push_back(lops.back()); lops.pop_back();
-  }
-  hlvmAssert(llvm::isa<llvm::Function>(lops.back()));
-  llvm::Function* F = llvm::cast<llvm::Function>(lops.back()); lops.pop_back();
+  const llvm::Value* arg = lops.back(); lops.pop_back();
+  while (!lops.empty() && !llvm::isa<llvm::Function>(arg)) {
+    args.push_back(const_cast<llvm::Value*>(arg));
+    arg = lops.back(); 
+    lops.pop_back();
+  }
+  hlvmAssert(sigTy->isVarArgs() || lops.size() == sigTy->size());
+  hlvmAssert(!sigTy->isVarArgs() || lops.size() >= sigTy->size());
+  hlvmAssert(llvm::isa<llvm::Function>(arg));
+  llvm::Function* F = const_cast<llvm::Function*>(
+      llvm::cast<llvm::Function>(arg));
   lops.push_back(new llvm::CallInst(F,args,"call_" + hFunc->getName(),lblk));
 }
 

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

==============================================================================
--- hlvm/trunk/hlvm/Pass/Pass.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Pass.cpp Sat Jul  7 19:02:02 2007
@@ -142,9 +142,9 @@
 PassManagerImpl::runOn(Linkable* l)
 {
   runPreOrder(l);
-  if (isa<Function>(l))
-    if (Block* b = cast<Function>(l)->getBlock())
-      runOn(b);
+  if (Function* F = dyn_cast<Function>(l))
+    if (Block* B = F->getBlock())
+      runOn(B);
   runPostOrder(l);
 }
 
@@ -158,15 +158,13 @@
     runPreOrder(const_cast<Type*>(TI->second));
     runPostOrder(const_cast<Type*>(TI->second));
   }
-  for (Bundle::cval_iterator CI = b->cval_begin(), CE = b->cval_end(); 
+  for (Bundle::value_iterator CI = b->value_begin(), CE = b->value_end(); 
        CI != CE; ++CI) {
-    runPreOrder(const_cast<ConstantValue*>(CI->second));
-    runPostOrder(const_cast<ConstantValue*>(CI->second));
-  }
-  for (Bundle::linkable_iterator LI = b->linkable_begin(), 
-       LE = b->linkable_end(); LI != LE; ++LI)
-  {
-    runOn(const_cast<Linkable*>(LI->second));
+    runPreOrder(const_cast<Value*>(*CI));
+    if (Function* F = dyn_cast<Function>(*CI))
+      if (Block* B = F->getBlock())
+        runOn(B);
+    runPostOrder(const_cast<Value*>(*CI));
   }
   runPostOrder(b);
 }

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

==============================================================================
--- hlvm/trunk/hlvm/Pass/Validate.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Validate.cpp Sat Jul  7 19:02:02 2007
@@ -578,7 +578,8 @@
 template<> inline void
 ValidateImpl::validate(SwitchOp* n)
 {
-  if (checkOperator(n,SwitchOpID,2,false)) {
+  if (checkOperator(n,SwitchOpID,2,false)) 
+  {
     if (n->getNumOperands() == 2)
       warning(n,"Why not just use a SelectOp?");
     if (n->getNumOperands() % 2 != 0)
@@ -587,17 +588,37 @@
 }
 
 template<> inline void
-ValidateImpl::validate(CallOp* n)
+ValidateImpl::validate(CallOp* op)
 {
-  checkOperator(n,CallOpID,0,false);
+  if (checkOperator(op,CallOpID,0,false)) 
+  {
+    hlvm::Function* F = op->getCalledFunction();
+    const SignatureType* sig = F->getSignature();
+    if (sig->isVarArgs() && (sig->size() >= op->getNumOperands()))
+        error(op,"Too few arguments for varargs function call");
+    else if (!sig->isVarArgs() && (sig->size() != op->getNumOperands()-1))
+      error(op,"Incorrect number of arguments for function call");
+    else 
+    {
+      unsigned opNum = 1;
+      for (SignatureType::const_iterator I = sig->begin(), E = sig->end(); 
+           I != E; ++I)
+        if ((*I)->getElementType() != op->getOperand(opNum++)->getType())
+          error(op,std::string("Argument #") + utostr(opNum-1) +
+              " has wrong type for function");
+    }
+  }
 }
 
 template<> inline void
 ValidateImpl::validate(AllocateOp* n)
 {
-  if (checkOperator(n,AllocateOpID,2)) {
-    if (const PointerType* PT = llvm::dyn_cast<PointerType>(n->getType())) {
-      if (const Type* Ty = PT->getElementType()) {
+  if (checkOperator(n,AllocateOpID,2)) 
+  {
+    if (const PointerType* PT = llvm::dyn_cast<PointerType>(n->getType())) 
+    {
+      if (const Type* Ty = PT->getElementType()) 
+      {
         if (!Ty->isSized())
           error(n,"Can't allocate an unsized type");
       } else 

Added: hlvm/trunk/test/error/argscall.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/error/argscall.hlx?rev=38294&view=auto

==============================================================================
--- hlvm/trunk/test/error/argscall.hlx (added)
+++ hlvm/trunk/test/error/argscall.hlx Sat Jul  7 19:02:02 2007
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/argscall.hlx">
+  <bundle id="argscall">
+    <signature id="no_args" result="void"/>
+    <signature id="one_arg" result="void">
+      <arg id="one" type="u32"/>
+    </signature>
+    <signature id="two_arg" result="double">
+      <arg id="one" type="u32"/>
+      <arg id="two" type="s32"/>
+    </signature>
+    <signature id="varargs" result="double" varargs="true">
+      <arg id="one" type="string"/>
+      <arg id="two" type="u32"/>
+    </signature>
+    <function id="none" type="one_arg" linkage="external"/>
+    <function id="one" type="one_arg" linkage="external"/>
+    <function id="two" type="one_arg" linkage="external"/>
+    <constant id="answer" type="u32">
+      <dec>42</dec>
+    </constant>
+    <program id="argscall">
+      <block>
+        <call>
+          <ref id="none"/>
+          <ref id="answer"/>
+        </call>
+        <call>
+          <ref id="one"/>
+        </call>
+        <call>
+          <ref id="two"/>
+          <ref id="answer"/>
+        </call>
+      </block>
+    </program>
+  </bundle>
+</hlvm>

Added: hlvm/trunk/test/error/argtype.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/error/argtype.hlx?rev=38294&view=auto

==============================================================================
--- hlvm/trunk/test/error/argtype.hlx (added)
+++ hlvm/trunk/test/error/argtype.hlx Sat Jul  7 19:02:02 2007
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/argscall.hlx">
+  <bundle id="argscall">
+    <signature id="two_arg" result="double">
+      <arg id="one" type="u32"/>
+      <arg id="two" type="s32"/>
+    </signature>
+    <constant id="answer" type="u32">
+      <dec>42</dec>
+    </constant>
+    <program id="argscall">
+      <block>
+        <call>
+          <ref id="two"/>
+          <ref id="answer"/>
+          <ref id="answer"/>
+        </call>
+      </block>
+    </program>
+  </bundle>
+</hlvm>

Added: hlvm/trunk/test/xml2xml/argscall.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/argscall.hlx?rev=38294&view=auto

==============================================================================
--- hlvm/trunk/test/xml2xml/argscall.hlx (added)
+++ hlvm/trunk/test/xml2xml/argscall.hlx Sat Jul  7 19:02:02 2007
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng" pubid="http://hlvm.org/src/hlvm/test/xml2xml/argscall.hlx">
+  <bundle id="argscall">
+    <signature id="no_args" result="void"/>
+    <signature id="one_arg" result="void">
+      <arg id="one" type="u32"/>
+    </signature>
+    <signature id="two_arg" result="double">
+      <arg id="one" type="u32"/>
+      <arg id="two" type="u32"/>
+    </signature>
+    <signature id="varargs" result="double" varargs="true">
+      <arg id="one" type="u32"/>
+      <arg id="two" type="u32"/>
+    </signature>
+    <constant id="answer" type="u32">
+      <dec>42</dec>
+    </constant>
+    <function id="none" type="no_args" linkage="external"/>
+    <function id="one" type="one_arg" linkage="external"/>
+    <function id="two" type="two_arg" linkage="external"/>
+    <function id="va" type="varargs" linkage="external"/>
+    <program id="argscall">
+      <block>
+        <call>
+          <ref id="none"/>
+        </call>
+        <call>
+          <ref id="one"/>
+          <ref id="answer"/>
+        </call>
+        <call>
+          <ref id="two"/>
+          <ref id="answer"/>
+          <ref id="answer"/>
+        </call>
+        <call>
+          <ref id="va"/>
+          <ref id="answer"/>
+          <ref id="answer"/>
+          <ref id="answer"/>
+        </call>
+      </block>
+    </program>
+  </bundle>
+</hlvm>





More information about the llvm-commits mailing list