Some initial shuffling to get Tock working with the new CIF.

This changes the TLP code to use CCSP's stand-alone mode, and gets rid of the
old KRoC wrapper stuff. It also changes occam_stop everywhere in order to pass
the number of arguments (since ExternalCallN needs that now), and cleans up the
interaction with the C++ backend a bit.
This commit is contained in:
Adam Sampson 2008-03-05 16:21:20 +00:00
parent 10d17f4b23
commit aff90d8d45
6 changed files with 80 additions and 88 deletions

23
Main.hs
View File

@ -129,21 +129,6 @@ getOpts argv =
(_,_,errs) -> error (concat errs ++ usageInfo header options)
where header = "Usage: tock [OPTION...] SOURCEFILE"
writeOccamWrapper :: Handle -> IO ()
writeOccamWrapper h = do
write "#INCLUDE \"cifccsp.inc\"\n"
write "#PRAGMA EXTERNAL \"PROC C.tock.main.init (INT raddr, CHAN BYTE in?, out!, err!) = 0\"\n"
write "#PRAGMA EXTERNAL \"PROC C.tock.main.free (VAL INT raddr) = 0\"\n"
write "PROC kroc.main (CHAN BYTE in?, out!, err!)\n"
write " INT addr:\n"
write " SEQ\n"
write " C.tock.main.init (addr, in?, out!, err!)\n"
write " cifccsp.startprocess (addr)\n"
write " C.tock.main.free (addr)\n"
write ":\n"
where
write = hPutStr h
main :: IO ()
main = do
argv <- getArgs
@ -226,12 +211,8 @@ compileFull inputFile
withOutputFile postCFile $ postCAnalyse sFile
-- Compile this new "post" C file into an object file
exec $ cCommand postCFile postOFile
-- Create a temporary occam file, and write the standard
-- occam wrapper into it
withOutputFile occFile $ liftIO . writeOccamWrapper
-- Use kroc to compile and link the occam file with the two
-- object files from the C compilation
exec $ krocLinkCommand occFile [oFile, postOFile] outputFile
-- Link the object files into a binary
exec $ cLinkCommand [oFile, postOFile] outputFile
-- For C++, just compile the source file directly into a binary
BackendCPPCSP ->

View File

@ -37,23 +37,24 @@ GenOrdAST$(EXEEXT): $(GenOrdAST_SOURCES)
ghc $(GHC_OPTS) -o GenOrdAST$(EXEEXT) -main-is GenOrdAST --make GenOrdAST -odir obj -hidir obj
TOCK_CFLAGS = @gnu89_inline@ @CPPFLAGS@ @CFLAGS@ -Wall `kroc --cflags` `kroc --ccincpath` -fno-strict-aliasing
# FIXME: -ldl is only necessary on some platforms for CCSP
TOCK_CLDFLAGS = @LDFLAGS@ `kroc --cclibpath` -lccsp -lpthread -ldl -lm
TOCK_CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ -Wall -ggdb3 -I. -fno-strict-aliasing
TOCK_CXXLDFLAGS = @LDFLAGS@ -lcppcsp2 -pthread
CompilerCommands.hs: Makefile
echo -e 'module CompilerCommands where\n' > CompilerCommands.hs
echo -e '--This file is auto-generated by Makefile.am\n' >> CompilerCommands.hs
echo -e 'import Data.List\n' >> CompilerCommands.hs
echo -e 'cCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cCommand inp out = "$(CC) $(TOCK_CFLAGS) -c -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs
echo -e 'cAsmCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cAsmCommand inp out = "$(CC) $(TOCK_CFLAGS) -S -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs
echo -e 'krocLinkCommand :: String -> [String] -> String -> String\n' >> CompilerCommands.hs
echo -e 'krocLinkCommand wrapper files out = "kroc -o " ++ out ++ " " ++ wrapper ++ " " ++ (concat (intersperse " " files)) ++ " -lcif"\n' >> CompilerCommands.hs
echo -e 'cxxCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cxxCommand inp out = "$(CXX) $(TOCK_CXXFLAGS) -o " ++ out ++ " " ++ inp ++ " $(TOCK_CXXLDFLAGS)"\n' >> CompilerCommands.hs
echo 'module CompilerCommands where' > CompilerCommands.hs
echo '--This file is auto-generated by Makefile.am' >> CompilerCommands.hs
echo 'import Data.List' >> CompilerCommands.hs
echo 'cCommand :: String -> String -> String' >> CompilerCommands.hs
echo 'cCommand inp out = "$(CC) $(TOCK_CFLAGS) -c -o " ++ out ++ " " ++ inp' >> CompilerCommands.hs
echo 'cAsmCommand :: String -> String -> String' >> CompilerCommands.hs
echo 'cAsmCommand inp out = "$(CC) $(TOCK_CFLAGS) -S -o " ++ out ++ " " ++ inp' >> CompilerCommands.hs
echo 'cLinkCommand :: [String] -> String -> String' >> CompilerCommands.hs
echo 'cLinkCommand files out = "$(CC) $(TOCK_CFLAGS) -o " ++ out ++ " " ++ (concat (intersperse " " files)) ++ " $(TOCK_CLDFLAGS)"' >> CompilerCommands.hs
echo 'cxxCommand :: String -> String -> String' >> CompilerCommands.hs
echo 'cxxCommand inp out = "$(CXX) $(TOCK_CXXFLAGS) -o " ++ out ++ " " ++ inp ++ " $(TOCK_CXXLDFLAGS)"' >> CompilerCommands.hs
# Both these results are near-identical. The -g flag to alex tells it to generate
# a lexer optimised for GHC. The other part of the rule inserts the

View File

@ -1,6 +1,6 @@
{-
Tock: a compiler for parallel languages
Copyright (C) 2007 University of Kent
Copyright (C) 2007, 2008 University of Kent
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@ -157,24 +157,43 @@ cgenTopLevel :: A.AST -> CGen ()
cgenTopLevel s
= do tell ["#include <tock_support.h>\n"]
cs <- get
(tlpName, chans) <- tlpInterface
tell ["extern int " ++ nameString n ++ "_stack_size;\n"
| n <- Set.toList $ csParProcs cs]
| n <- tlpName : (Set.toList $ csParProcs cs)]
sequence_ $ map (call genForwardDeclaration) (listify (const True :: A.Specification -> Bool) s)
call genStructured s (\m _ -> tell ["\n#error Invalid top-level item: ", show m])
(name, chans) <- tlpInterface
tell ["void tock_main (Process *me, Channel *in, Channel *out, Channel *err) {\n"]
genName name
tell [" (me"]
sequence_ [tell [", "] >> call genTLPChannel c | (_,c) <- chans]
tell [");\n"]
tell ["}\n"]
tell ["void _tock_main_init (int *ws) {"]
tell ["Process *p = ProcAlloc (tock_main, 65536, 3,"]
tell ["(Channel *) ws[1], (Channel *) ws[2], (Channel *) ws[3]);"]
tell ["*((int *) ws[0]) = (int) p;"]
tell ["}"]
tell ["void _tock_main_free (int *ws) {ProcAllocClean ((Process *) ws[0]);}"]
tell ["void tock_main (Workspace wptr) {\n\
\ Workspace tlp = ProcAlloc (wptr, ", show $ length chans, ", "]
genName tlpName
tell ["_stack_size);\n"]
sequence_ [do tell [" ProcParam (wptr, tlp, " ++ show i ++ ", "]
call genTLPChannel c
tell [");\n"]
| (i, (_, c)) <- zip [(0 :: Int)..] chans]
tell ["\n\
\ LightProcBarrier bar;\n\
\ LightProcBarrierInit (wptr, &bar, 1);\n\
\ LightProcStart (wptr, &bar, tlp, (Process) "]
genName tlpName
tell [");\n\
\ LightProcBarrierWait (wptr, &bar);\n\
\ Shutdown (wptr);\n\
\}\n\
\\n\
\int main (int argc, char *argv[]) {\n\
\ if (!ccsp_init ())\n\
\ return 1;\n\
\\n\
\ Workspace p = ProcAllocInitial (0, 512);\n\
\ ProcStartInitial (p, tock_main);\n\
\\n\
\ // NOTREACHED\n\
\ return 0;\n\
\}\n"]
--}}}
--{{{ utilities

View File

@ -83,10 +83,10 @@ old_CFLAGS="$CFLAGS"
old_CPPFLAGS="$CPPFLAGS"
CFLAGS="$kroc_incpath"
CPPFLAGS="$kroc_incpath"
AC_CHECK_HEADER([cifccsp.h],[HAVE_CIFCCSP=true],[HAVE_CIFCCSP=false])
AC_CHECK_HEADER([cif.h],[HAVE_CIF=true],[HAVE_CIF=false])
if test "x$HAVE_CIFCCSP" = "xfalse"; then
AC_MSG_WARN([cifccsp.h not found; you will not be able to compile output from the C backend on this machine])
if test "x$HAVE_CIF" = "xfalse"; then
AC_MSG_WARN([cif.h not found; you will not be able to compile output from the C backend on this machine])
ccsp_kroc_available=false
fi
CFLAGS="$old_CFLAGS"

View File

@ -1,6 +1,6 @@
/*
* C99 support code for Tock programs
* Copyright (C) 2007 University of Kent
* Copyright (C) 2007, 2008 University of Kent
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@ -27,14 +27,8 @@
#include <stdio.h>
#include <math.h>
//For C++CSP:
#ifndef NO_CIFCCSP
#include <cifccsp.h>
#else
#define EXTERNAL_CALLN(F,I,args...) (F)((I),##args)
#define EXTERNAL_CALL(F) (F)()
#define SetErr()
#define Channel int
#ifndef BACKEND_CPPCSP
#include <cif.h>
#endif
//{{{ mostneg/mostpos
@ -67,26 +61,23 @@
#endif
//}}}
//{{{ helper functions to simplify the code generation
static inline void tock_init_chan_array(Channel*, Channel**, int) occam_unused;
static inline void tock_init_chan_array(Channel* pointTo, Channel** pointFrom, int count) {
//{{{ channel array initialisation
static inline void tock_init_chan_array (Channel *, Channel **, int) occam_unused;
static inline void tock_init_chan_array (Channel *pointTo, Channel **pointFrom, int count) {
for (int i = 0; i < count; i++) {
pointFrom[i] = &(pointTo[i]);
}
}
}
//}}}
//{{{ runtime check functions
//C++CSP may have defined this function already:
#ifndef occam_stop
#define occam_stop(pos, format, args...) \
#ifndef BACKEND_CPPCSP
#define occam_stop(pos, nargs, format, args...) \
do { \
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
ExternalCallN (fprintf, 3 + nargs, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
SetErr (); \
} while (0)
#endif //occam_stop
#endif
static inline int occam_check_slice (int, int, int, const char *) occam_unused;
static inline int occam_check_slice (int start, int count, int limit, const char *pos) {
@ -94,21 +85,21 @@ static inline int occam_check_slice (int start, int count, int limit, const char
if (count != 0 && (start < 0 || start >= limit
|| end < 0 || end > limit
|| count < 0)) {
occam_stop (pos, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit);
occam_stop (pos, 4, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit);
}
return count;
}
static inline int occam_check_index (int, int, const char *) occam_unused;
static inline int occam_check_index (int i, int limit, const char *pos) {
if (i < 0 || i >= limit) {
occam_stop (pos, "invalid array index %d (should be 0 <= i < %d)", i, limit);
occam_stop (pos, 3, "invalid array index %d (should be 0 <= i < %d)", i, limit);
}
return i;
}
static inline int occam_check_retype (int, int, const char *) occam_unused;
static inline int occam_check_retype (int src, int dest, const char *pos) {
if (src % dest != 0) {
occam_stop (pos, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", dest, src);
occam_stop (pos, 3, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", dest, src);
}
return src / dest;
}
@ -119,7 +110,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_range_check_##type (type, type, type, const char *) occam_unused; \
static inline type occam_range_check_##type (type lower, type upper, type n, const char *pos) { \
if (n < lower || n > upper) { \
occam_stop (pos, "invalid value in conversion " format " (should be " format " <= i <= " format ")", n, lower, upper); \
occam_stop (pos, 4, "invalid value in conversion " format " (should be " format " <= i <= " format ")", n, lower, upper); \
} \
return n; \
}
@ -143,7 +134,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_div_##type (type, type, const char *) occam_unused; \
static inline type occam_div_##type (type a, type b, const char *pos) { \
if (b == 0) { \
occam_stop (pos, "divide by zero"); \
occam_stop (pos, 1, "divide by zero"); \
} \
return a / b; \
}
@ -159,7 +150,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_rem_##type (type, type, const char *) occam_unused; \
static inline type occam_rem_##type (type a, type b, const char *pos) { \
if (b == 0) { \
occam_stop (pos, "modulo by zero"); \
occam_stop (pos, 1, "modulo by zero"); \
} \
if (a < 0) { \
return -((-a) % (b < 0 ? -b : b)); \
@ -174,7 +165,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_rem_##type (type, type, const char *) occam_unused; \
static inline type occam_rem_##type (type a, type b, const char *pos) { \
if (b == 0) { \
occam_stop (pos, "modulo by zero"); \
occam_stop (pos, 1, "modulo by zero"); \
} \
type i = round (a / b); \
return a - (i * b); \
@ -184,7 +175,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_lshift_##type (type, int, const char*) occam_unused; \
static inline type occam_lshift_##type (type a, int b, const char* pos) { \
if (b < 0 || b > (int)(sizeof(type) * CHAR_BIT)) { \
occam_stop (pos, "left shift by negative value or value (strictly) greater than number of bits in type"); \
occam_stop (pos, 1, "left shift by negative value or value (strictly) greater than number of bits in type"); \
} else if (b == (int)(sizeof(type) * CHAR_BIT)) { \
return 0; \
} else { \
@ -194,7 +185,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
static inline type occam_rshift_##type (type, int, const char*) occam_unused; \
static inline type occam_rshift_##type (type a, int b, const char* pos) { \
if (b < 0 || b > (int)(sizeof(type) * CHAR_BIT)) { \
occam_stop (pos, "right shift by negative value or value (strictly) greater than number of bits in type"); \
occam_stop (pos, 1, "right shift by negative value or value (strictly) greater than number of bits in type"); \
} else if (b == (int)(sizeof(type) * CHAR_BIT)) { \
return 0; \
} else { \
@ -249,7 +240,7 @@ MAKE_TIMES(uint8_t)
static inline uint8_t occam_rem_uint8_t (uint8_t, uint8_t, const char *) occam_unused;
static inline uint8_t occam_rem_uint8_t (uint8_t a, uint8_t b, const char *pos) {
if (b == 0) {
occam_stop (pos, "modulo by zero");
occam_stop (pos, 1, "modulo by zero");
}
return a % b;
}

View File

@ -1,6 +1,6 @@
/*
* C++ support code for Tock programs
* Copyright (C) 2007 University of Kent
* Copyright (C) 2007, 2008 University of Kent
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@ -31,14 +31,14 @@ public:
}
};
#define occam_stop(pos, format, args...) \
#define occam_stop(pos, nargs, format, args...) \
do { \
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
SetErr (); \
fprintf(stderr, "Program stopped at %s: " format "\n", pos, ##args); \
throw StopException(""); \
} while (0)
#define NO_CIFCCSP
#define BACKEND_CPPCSP
#define Channel int
#include "tock_support.h"
@ -195,7 +195,7 @@ class tockArrayView
//Check it fits exactly:
if ((totalSourceBytes / totalDim) % sizeof(T) != 0)
{
occam_stop ("","invalid size for RETYPES/RESHAPES (%d does not divide into %d)", (totalSourceBytes / totalDim), sizeof(T));
occam_stop ("", 3, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", (totalSourceBytes / totalDim), sizeof(T));
}
//Set the size of the unknown dimension: