[llvm-commits] [hlvm] r38162 - in /hlvm/trunk/hlvm: CodeGen/LLVMGenerator.cpp CodeGen/program.cxx Runtime/FileIO.cpp Runtime/Main.cpp Runtime/Memory.h Runtime/Program.cpp Runtime/Program.h Runtime/SConscript Runtime/String.cpp Runtime/Utilities.h Runtime/hlvm_get_programs.ll

Reid Spencer reid at x10sys.com
Sat Jul 7 17:00:36 PDT 2007


Author: reid
Date: Sat Jul  7 19:00:36 2007
New Revision: 38162

URL: http://llvm.org/viewvc/llvm-project?rev=38162&view=rev
Log:
Finally get the "return 0" test case working properly. This required a fair
bit of synchronization between the compiler and the runtime. The appending
linkage for program entry points caused most of the grief.

Added:
    hlvm/trunk/hlvm/Runtime/Utilities.h
    hlvm/trunk/hlvm/Runtime/hlvm_get_programs.ll
Modified:
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/CodeGen/program.cxx
    hlvm/trunk/hlvm/Runtime/FileIO.cpp
    hlvm/trunk/hlvm/Runtime/Main.cpp
    hlvm/trunk/hlvm/Runtime/Memory.h
    hlvm/trunk/hlvm/Runtime/Program.cpp
    hlvm/trunk/hlvm/Runtime/Program.h
    hlvm/trunk/hlvm/Runtime/SConscript
    hlvm/trunk/hlvm/Runtime/String.cpp

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

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:00:36 2007
@@ -67,17 +67,35 @@
 
 class LLVMGeneratorPass : public hlvm::Pass
 {
+  typedef std::vector<llvm::Module*> ModuleList;
+  typedef std::vector<llvm::Value*> OperandList;
+  ModuleList modules;        ///< The list of modules we construct
+  llvm::Module*     lmod;    ///< The current module we're generation 
+  llvm::Function*   lfunc;   ///< The current LLVM function we're generating 
+  llvm::BasicBlock* lblk;    ///< The current LLVM block we're generating
+  llvm::BasicBlock::InstListType linst; 
+  OperandList lops;          ///< The current list of instruction operands
+  llvm::TypeSymbolTable ltypes; ///< The cached LLVM types we've generated
+    ///< The current LLVM instructions we're generating
+  const AST* ast;            ///< The current Tree we're traversing
+  const Bundle* bundle;      ///< The current Bundle we're traversing
+  const hlvm::Function* function;  ///< The current Function we're traversing
+  const Block* block;        ///< The current Block we're traversing
+  std::vector<llvm::Function*> progs; ///< The list of programs to emit
+  const llvm::FunctionType* entry_FT; ///< The llvm function type for programs
+
   public:
     LLVMGeneratorPass(const AST* tree)
       : Pass(0,Pass::PreAndPostOrderTraversal),
       modules(), lmod(0), lfunc(0), lblk(0), linst(), lops(), ltypes(),
-      ast(tree),   bundle(0), function(0), block(0) { }
+      ast(tree),   bundle(0), function(0), block(0), entry_FT(0) { }
     ~LLVMGeneratorPass() { }
 
   /// Conversion functions
   inline const llvm::Type* getType(const hlvm::Type* ty);
   inline llvm::GlobalValue::LinkageTypes getLinkageTypes(LinkageKinds lk);
   inline std::string getLinkageName(LinkageItem* li);
+  const llvm::FunctionType* getProgramFT();
 
   /// Generators
   inline void gen(Bundle* b);
@@ -109,26 +127,8 @@
   virtual void handleTerminate();
 
   inline llvm::Module* linkModules();
-
-private:
-  typedef std::vector<llvm::Module*> ModuleList;
-  typedef std::vector<llvm::Value*> OperandList;
-  ModuleList modules;        ///< The list of modules we construct
-  llvm::Module*     lmod;    ///< The current module we're generation 
-  llvm::Function*   lfunc;   ///< The current LLVM function we're generating 
-  llvm::BasicBlock* lblk;    ///< The current LLVM block we're generating
-  llvm::BasicBlock::InstListType linst; 
-  OperandList lops;          ///< The current list of instruction operands
-  llvm::TypeSymbolTable ltypes; ///< The cached LLVM types we've generated
-    ///< The current LLVM instructions we're generating
-  const AST* ast;            ///< The current Tree we're traversing
-  const Bundle* bundle;      ///< The current Bundle we're traversing
-  const hlvm::Function* function;  ///< The current Function we're traversing
-  const Block* block;        ///< The current Block we're traversing
-  std::vector<llvm::Function*> progs; ///< The list of programs to emit at the end
 };
 
-
 const llvm::Type*
 LLVMGeneratorPass::getType(const hlvm::Type* ty)
 {
@@ -343,12 +343,27 @@
 std::string
 LLVMGeneratorPass::getLinkageName(LinkageItem* lk)
 {
-  if (lk->isProgram())
-    return std::string("_hlvm_entry_") + lk->getName();
+  // if (lk->isProgram())
+    // return std::string("_hlvm_entry_") + lk->getName();
   // FIXME: This needs to incorporate the bundle name
   return lk->getName();
 }
 
+const llvm::FunctionType*
+LLVMGeneratorPass::getProgramFT()
+{
+  if (!entry_FT) {
+    // Get the type of function that all entry points must have
+    std::vector<const llvm::Type*> arg_types;
+    arg_types.push_back(llvm::Type::IntTy);
+    arg_types.push_back(
+      llvm::PointerType::get(llvm::PointerType::get(llvm::Type::SByteTy)));
+    entry_FT = llvm::FunctionType::get(llvm::Type::IntTy,arg_types,false);
+    lmod->addTypeName("hlvm_program_signature",entry_FT);
+  }
+  return entry_FT;
+}
+
 void
 LLVMGeneratorPass::gen(hlvm::Function* f)
 {
@@ -365,8 +380,7 @@
   std::string linkageName = getLinkageName(p);
 
   // Get the FunctionType for entry points (programs)
-  const llvm::FunctionType* entry_signature = 
-    llvm::cast<llvm::FunctionType>(getType(p->getSignature()));
+  const llvm::FunctionType* entry_signature = getProgramFT();
 
   // Create a new function for the program based on the signature
   lfunc = new llvm::Function(entry_signature,
@@ -436,8 +450,7 @@
 LLVMGeneratorPass::handleTerminate()
 {
   // Get the type of function that all entry points must have
-  const llvm::FunctionType* entry_signature = 
-    llvm::cast<llvm::FunctionType>(getType(ast->getProgramType())); 
+  const llvm::FunctionType* entry_signature = getProgramFT();
 
   // Define the type of the array elements (a structure with a pointer to
   // a string and a pointer to the function).
@@ -496,7 +509,7 @@
     /*isConstant=*/true,
     /*Linkage=*/llvm::GlobalValue::AppendingLinkage,
     /*Initializer=*/entry_points_initializer,
-    /*Name=*/"_hlvm_entry_points",
+    /*Name=*/"hlvm_programs",
     /*Parent=*/lmod
   );
 }

Modified: hlvm/trunk/hlvm/CodeGen/program.cxx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/program.cxx?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/program.cxx (original)
+++ hlvm/trunk/hlvm/CodeGen/program.cxx Sat Jul  7 19:00:36 2007
@@ -1,23 +1,34 @@
-#include "string.h"
+//===-- Input To llvm2cpp For Program Fragments -----------------*- C++ -*-===//
+//
+//                      High Level Virtual Machine (HLVM)
+//
+// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
+//
+// This software is free software; you can redistribute it and/or modify it 
+// under the terms of the GNU Lesser General Public License as published by 
+// the Free Software Foundation; either version 2.1 of the License, or (at 
+// your option) any later version.
+//
+// This software is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
+// more details.
+//
+// You should have received a copy of the GNU Lesser General Public License 
+// along with this library in the file named LICENSE.txt; if not, write to the 
+// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+// MA 02110-1301 USA
+//
+//===----------------------------------------------------------------------===//
+/// @file hlvm/CodeGen/program.cxx     
+/// @author Reid Spencer <rspencer at x10sys.com>
+/// @date 2006/05/12
+/// @since 0.1.0
+/// @brief Input to llvm2cpp for Program related code generation
+//===----------------------------------------------------------------------===//
 
-extern "C" {
-
-struct _hlvm_program_args {
-  uint32_t argc;
-  _hlvm_string* argv;
-};
-
-typedef uint32_t (*_hlvm_program_type)(_hlvm_program_args* args);
+#include <hlvm/Runtime/Program.h>
 
-struct _hlvm_programs_element {
-  const char* program_name;
-  _hlvm_program_type program_entry;
-};
-
-extern uint32_t return0_prog(_hlvm_program_args* args);
-
-_hlvm_programs_element _hlvm_programs[1] = {
-  { "return0", return0_prog }
-};
+extern "C" {
 
 }

Modified: hlvm/trunk/hlvm/Runtime/FileIO.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/FileIO.cpp?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/FileIO.cpp (original)
+++ hlvm/trunk/hlvm/Runtime/FileIO.cpp Sat Jul  7 19:00:36 2007
@@ -29,6 +29,7 @@
 
 #include <hlvm/Runtime/FileIO.h>
 #include <apr-1/apr_file_io.h>
+#include <hlvm/Runtime/Utilities.h>
 
 namespace 
 {

Modified: hlvm/trunk/hlvm/Runtime/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/Main.cpp?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/Main.cpp (original)
+++ hlvm/trunk/hlvm/Runtime/Main.cpp Sat Jul  7 19:00:36 2007
@@ -35,36 +35,41 @@
 #include <string.h>
 #include <iostream>
 
-namespace {
-
 using namespace llvm;
 
-static cl::opt<std::string>
-ProgramToRun(cl::Positional, cl::desc("URI of program to run"));
+namespace {
+
+/// Option to indicate which program to start running
+static cl::opt<std::string> Start("start",
+  cl::Required,
+  cl::desc("Specify the starting point for the program"),
+  cl::value_desc("program URI")
+);
 
+/// This is the Main class that handles the basic execution framework for
+/// all HLVM programs.
 class Main {
   int argc;
   char ** argv;
 public:
+  /// Construct the "Main" and handle argument processing.
   Main(int ac, char**av) : argc(ac), argv(av) {
+    llvm::cl::SetVersionPrinter(hlvm::print_version);
     llvm::cl::ParseCommandLineOptions(argc,argv,"High Level Virtual Machine\n");
   }
+
+  /// Run the requested program.
   int run() {
-    hlvm_program_type func = hlvm_find_program(ProgramToRun.c_str());
+    // First, find the function that represents the start point.
+    hlvm_program_type func = hlvm_find_program(Start.c_str());
+
+    // If we got a start function ..
     if (func) {
-      hlvm_program_args args;
-      args.argc = argc - 1;
-      args.argv = (hlvm_string*) 
-        hlvm_allocate_array(argc-1, sizeof(hlvm_string));
-      for (unsigned i = 0; i < args.argc; i++) {
-        uint64_t len = strlen(argv[i]);
-        args.argv[i].len = len;
-        args.argv[i].str = (const char*)
-          hlvm_allocate_array(len, sizeof(args.argv[i].str[0]));
-      }
-      return (*func)(&args);
+      // Invoke it.
+      return (*func)(argc-1,(signed char**)&argv[1]);
     } else {
-      std::cerr << argv[0] << ": Program '" << ProgramToRun << "' not found.\n";
+      // Give an error
+      std::cerr << argv[0] << ": Program '" << Start << "' not found.\n";
       return 1;
     }
   }
@@ -74,6 +79,10 @@
 
 extern "C" {
 
+/// This is the function called from the real main() in hlvm/tools/hlvm.  We 
+/// do this because we don't want to expose the "Main" class to the outside
+/// world. The interface to the HLVM Runtime is C even though the
+/// implementation uses C++.
 int hlvm_runtime_main(int argc, char**argv)
 {
   int result = 0;

Modified: hlvm/trunk/hlvm/Runtime/Memory.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/Memory.h?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/Memory.h (original)
+++ hlvm/trunk/hlvm/Runtime/Memory.h Sat Jul  7 19:00:36 2007
@@ -1,4 +1,4 @@
-//===-- Runtime Program Interface -------------------------------*- C++ -*-===//
+//===-- Runtime Memory Management Interface ---------------------*- C++ -*-===//
 //
 //                      High Level Virtual Machine (HLVM)
 //
@@ -20,11 +20,11 @@
 // MA 02110-1301 USA
 //
 //===----------------------------------------------------------------------===//
-/// @file hlvm/Runtime/Program.h
+/// @file hlvm/Runtime/Memory.h
 /// @author Reid Spencer <rspencer at reidspencer.com> (original author)
-/// @date 2006/05/24
+/// @date 2006/06/05
 /// @since 0.1.0
-/// @brief Declares the interface to the runtime program facilities
+/// @brief Declares the interface to the runtime memory management facilities
 //===----------------------------------------------------------------------===//
 
 #ifndef HLVM_RUNTIME_MEMORY_H

Modified: hlvm/trunk/hlvm/Runtime/Program.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/Program.cpp?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/Program.cpp (original)
+++ hlvm/trunk/hlvm/Runtime/Program.cpp Sat Jul  7 19:00:36 2007
@@ -37,15 +37,23 @@
 
 extern "C" {
 
-hlvm_programs_element hlvm_programs[1];
+/// Declare the external function that gets use the first element in
+/// the hlvm_programs appending array. This function is implemented in the
+/// hlvm_get_programs.ll file.
+extern hlvm_programs_element* hlvm_get_programs();
 
+/// Search the list of programs for a matching entry point. This uses a dumb
+/// linear search but it should be okay because the number of program entry
+/// points in any given executable should not be huge. If it is, someone is
+/// designing their software poorly and they deserve what they get :)
 hlvm_program_type 
 hlvm_find_program(const char* uri)
 {
-  hlvm_programs_element* p = &hlvm_programs[0];
+  hlvm_programs_element* p = hlvm_get_programs();
   while (p && p->program_entry) {
     if (strcmp(p->program_name,uri) == 0)
       return p->program_entry;
+    ++p;
   }
   return 0;
 }

Modified: hlvm/trunk/hlvm/Runtime/Program.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/Program.h?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/Program.h (original)
+++ hlvm/trunk/hlvm/Runtime/Program.h Sat Jul  7 19:00:36 2007
@@ -34,20 +34,17 @@
 
 extern "C" {
 
-struct hlvm_program_args {
-  uint32_t argc;
-  hlvm_string* argv;
-};
-
-typedef uint32_t (*hlvm_program_type)(hlvm_program_args* args);
+/// This is the type of a program entry point function.
+typedef int (*hlvm_program_type)(int, signed char **);
 
+/// This is the type of the appending array of program entry elements
 struct hlvm_programs_element {
   const char* program_name;
   hlvm_program_type program_entry;
 };
 
-extern hlvm_programs_element hlvm_programs[];
-
+/// This function searches the hlvm_programs array for an entry matching
+/// uri and returns a pointer to the corresponding program.
 extern hlvm_program_type hlvm_find_program(const char* uri);
 
 }

Modified: hlvm/trunk/hlvm/Runtime/SConscript
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/SConscript?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/SConscript (original)
+++ hlvm/trunk/hlvm/Runtime/SConscript Sat Jul  7 19:00:36 2007
@@ -23,7 +23,10 @@
 Import('env')
 from build import hlvm
 hlvm.GetBytecode(env)
-env.BytecodeArchive('HLVMRuntime.bca',hlvm.GetAllCXXFiles(env))
-lib = env.SharedLibrary('HLVMRuntime',hlvm.GetAllCXXFiles(env))
+env.BytecodeArchive('HLVMRuntime.bca',hlvm.GetAllCXXFiles(env) + [
+  'hlvm_get_programs.ll'])
+asm = env.bc2s(source=['hlvm_get_programs.bc'])
+obj = env.StaticObject(source=asm)
+lib = env.StaticLibrary('HLVMRuntime',hlvm.GetAllCXXFiles(env) + obj)
 hlvm.InstallLibrary(env,lib)
 hlvm.InstallHeader(env,hlvm.GetFiles(env,'*.h'))

Modified: hlvm/trunk/hlvm/Runtime/String.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/String.cpp?rev=38162&r1=38161&r2=38162&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Runtime/String.cpp (original)
+++ hlvm/trunk/hlvm/Runtime/String.cpp Sat Jul  7 19:00:36 2007
@@ -22,7 +22,7 @@
 //===----------------------------------------------------------------------===//
 /// @file hlvm/Runtime/String.cpp
 /// @author Reid Spencer <rspencer at reidspencer.org> (original author)
-/// @date 2006/05/24
+/// @date 2006/05/25
 /// @since 0.1.0
 /// @brief Implements the functions for runtime string support
 //===----------------------------------------------------------------------===//

Added: hlvm/trunk/hlvm/Runtime/Utilities.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/Utilities.h?rev=38162&view=auto

==============================================================================
--- hlvm/trunk/hlvm/Runtime/Utilities.h (added)
+++ hlvm/trunk/hlvm/Runtime/Utilities.h Sat Jul  7 19:00:36 2007
@@ -0,0 +1,53 @@
+//===-- Runtime Utilities Interface -----------------------------*- C++ -*-===//
+//
+//                      High Level Virtual Machine (HLVM)
+//
+// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
+//
+// This software is free software; you can redistribute it and/or modify it 
+// under the terms of the GNU Lesser General Public License as published by 
+// the Free Software Foundation; either version 2.1 of the License, or (at 
+// your option) any later version.
+//
+// This software is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
+// more details.
+//
+// You should have received a copy of the GNU Lesser General Public License 
+// along with this library in the file named LICENSE.txt; if not, write to the 
+// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+// MA 02110-1301 USA
+//
+//===----------------------------------------------------------------------===//
+/// @file hlvm/Runtime/Utilities.h
+/// @author Reid Spencer <rspencer at reidspencer.com> (original author)
+/// @date 2006/06/05
+/// @since 0.1.0
+/// @brief Declares the interface to the runtime utilities
+//===----------------------------------------------------------------------===//
+
+#ifndef HLVM_RUNTIME_UTILITIES_H
+#define HLVM_RUNTIME_UTILITIES_H
+
+#include <hlvm/Base/Config.h>
+
+/// This is the HLVM runtime assert macro. It is very much similar to
+/// the <cassert> version but without some of the overhead. It also lets
+/// us take control of what to do when an assertion happens. The standard
+/// implementation just prints and aborts.
+#define hlvm_assert(expr) \
+  (static_cast<void>((expr) ? 0 : \
+    (hlvm_assert_fail(" #expr ", __FILE__, __LINE__))))
+
+extern "C" 
+{
+
+/// This function gets called by the hlvm_assert macro, and in other situations
+/// where a "panic" happens. It provides the proper escape mechanism given the
+/// configuration of the runtime.
+void hlvm_assert_fail(const char* expression, const char* file, int line_num);
+
+}
+
+#endif

Added: hlvm/trunk/hlvm/Runtime/hlvm_get_programs.ll
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Runtime/hlvm_get_programs.ll?rev=38162&view=auto

==============================================================================
--- hlvm/trunk/hlvm/Runtime/hlvm_get_programs.ll (added)
+++ hlvm/trunk/hlvm/Runtime/hlvm_get_programs.ll Sat Jul  7 19:00:36 2007
@@ -0,0 +1,57 @@
+;===-- Runtime Programs Glue -------------------------------------*- LLVM -*-===
+;
+;                      High Level Virtual Machine (HLVM)
+;
+; Copyright (C) 2006 Reid Spencer. All Rights Reserved.
+;
+; This software is free software; you can redistribute it and/or modify it 
+; under the terms of the GNU Lesser General Public License as published by 
+; the Free Software Foundation; either version 2.1 of the License, or (at 
+; your option) any later version.
+;
+; This software is distributed in the hope that it will be useful, but WITHOUT
+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+; FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
+; more details.
+;
+; You should have received a copy of the GNU Lesser General Public License 
+; along with this library in the file named LICENSE.txt; if not, write to the 
+; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+; MA 02110-1301 USA
+;
+;===-------------------------------------------------------------------------===
+;
+; This file provides some glue between the runtime library and the HLVM compiler
+; It arranges to get the address of an "appending linkage" constant array via
+; the hlvm_get_programs() function. This is necessary to be done in LLVM 
+; assembly because you can't express an "appending linkage" constant array in
+; C or C++. Additionally, this provides the null-terminator sentinel that marks
+; the end of the array. When the compiler generates code for an HLVM program, it
+; creates an entry in this array. Since it is legal to have multiple entry 
+; points in HLVM, the resulting array (collected from all Program compilations)
+; will contain the complete set of entry points that can be started. This is
+; useful where a group of related programs should share the same executable. For
+; example, "rm", "cp", "mkdir", "rmdir", etc. all have similar needs and, with
+; LLVM, could all be in the same executable. This file makes that magic 
+; happen.
+; 
+;===-------------------------------------------------------------------------===
+;
+; This is the type for the elements of the hlvm_programs array. Each element
+; contains a pointer to a string for the name of the program and a pointer to
+; the entry function.
+%hlvm_programs_element = type { sbyte*, int (int, sbyte**)* }
+
+; This is the appending constant array with 1 element here that is zero
+; initialized. This forms the zero-terminator in the array. This module MUST
+; be linked LAST in order for this to work.
+%hlvm_programs = appending constant [1 x %hlvm_programs_element] zeroinitializer
+
+; End of declarations, start the implementation
+implementation
+
+; This is a very simple function to get the address of %hlvm_programs.
+%hlvm_programs_element* %hlvm_get_programs() {
+entry:
+  ret %hlvm_programs_element* getelementptr([1 x %hlvm_programs_element]* %hlvm_programs, int 0, int 0)
+}





More information about the llvm-commits mailing list