[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