Commit 1b651fb9 authored by Artem Shinkarov's avatar Artem Shinkarov
Browse files

Merge tag 'v1.3.3-MijasCosta'

Fixing broken ubuntu dependencies
parents 1954b48d 09335809
......@@ -41,7 +41,7 @@ GLOBAL (unsigned int, max_allocated_mem, 0, xfree_dummy, )
*/
GLOBAL (tool_t, tool, TOOL_sac2c, xfree_dummy, )
GLOBAL (char *, toolname, NULL, xfree_dummy, )
GLOBAL (const char *, toolname, NULL, xfree_dummy, )
/*
* Syntax tree root
......@@ -1320,8 +1320,11 @@ GLOBAL (int, cuda_1d_block_small, 0, xfree_dummy, )
GLOBAL (int, cuda_2d_block_x, 0, xfree_dummy, )
GLOBAL (int, cuda_2d_block_y, 0, xfree_dummy, )
GLOBAL (int, cuda_blocking_factor, 0, xfree_dummy, )
GLOBAL (unsigned int, cuda_max_x_dim, 0, xfree_dummy, )
GLOBAL (unsigned int, cuda_max_yz_dim, 0, xfree_dummy, ) /* for both the Y and Z dimensions */
GLOBAL (unsigned int, cuda_max_x_grid, 0, xfree_dummy, )
GLOBAL (unsigned int, cuda_max_yz_grid, 0, xfree_dummy, ) /* for both the Y and Z dimensions */
GLOBAL (unsigned int, cuda_max_xy_block, 0, xfree_dummy, )
GLOBAL (unsigned int, cuda_max_z_block, 0, xfree_dummy, )
GLOBAL (unsigned int, cuda_max_threads_block, 0, xfree_dummy, )
/*
* DistMem backend options
......
......@@ -22,7 +22,7 @@ mallocphaseinfo_t phasetable[PH_final + 1] = {{0, 0, 0, 0, 0, 0, 0, 0}};
static FILE *mreport = 0;
void *
_MEMmalloc (int size, char *file, int line, const char *func)
_MEMmalloc (int size, const char *file, int line, const char *func)
{
#ifndef DBUG_OFF
void *ptr;
......
......@@ -3,6 +3,7 @@
#include "types.h"
#include "uthash.h"
#include "fun-attrs.h"
/*
* mallocinfo_t is a struct we use to store information about a malloc
......@@ -16,7 +17,7 @@ typedef struct mallocinfo_t {
bool wasintree;
bool isnode;
nodetype type;
char *file;
const char *file;
const char *callingfunc;
int line;
int occurrence;
......@@ -50,7 +51,7 @@ extern mallocphaseinfo_t phasetable[]; // needed by check_mem
*
* Should be used instead of `malloc'.
*/
extern void *_MEMmalloc (int size, char *file, int line,
extern void *_MEMmalloc (int size, const char *file, int line,
const char *func) FUN_ATTR_MALLOC;
#define MEMmalloc(size) _MEMmalloc (size, __FILE__, __LINE__, __func__)
#define MEMmallocAt(size, file, line) _MEMmalloc (size, file, line, __func__)
......
......@@ -850,6 +850,7 @@ PrintRuntimeTraceOptions (void)
" p: Trace primitive function calls.\n"
" w: Trace with-loop execution.\n"
" s: Trace array accesses.\n"
" g: Trace CUDA runtime.\n"
" t: Trace multi-threading specific operations.\n"
" c: Trace runtime enviroment init/exit when\n"
" using SAC libraries in C programs.\n"
......
......@@ -416,8 +416,8 @@ lexer_read_user_op (struct lexer *lex, struct token *tok, char **buf, size_t *si
}
/* FIXME we can adjust it later. */
if ((i == 0 && isdigit (c)) || c == '"' || c == '\'' || c == '(' || c == ','
|| c == '[' || c == ']' || c == ']') {
if ((i == 0 && isdigit (c)) || c == '"' || c == '\'' || c == ',' || c == '['
|| c == ']') {
lexer_ungetch (lex, c);
error_loc (lex->loc,
"unallowed symbol `%c' inside the name "
......@@ -431,6 +431,12 @@ lexer_read_user_op (struct lexer *lex, struct token *tok, char **buf, size_t *si
}
buffer_add_char (buf, &index, size, 0);
if (strlen (*buf) == 0) {
error_loc (lex->loc, "the length of the name of the function is zero");
return tok_unknown;
}
search = trie_search (lex->trie, *buf, strlen (*buf));
if (search == TRIE_NOT_LAST) {
if (!is_normal_id (*buf))
......
......@@ -260,27 +260,6 @@ lexer_change_file_name (struct lexer *lex, const char *fname)
return f->name;
}
static inline bool
is_operator_symbol (const int c)
{
return !(isspace (c) || isalnum (c) || c == '(' || c == ')' || c == '[' || c == ']'
|| c == '{' || c == '}' || c == ';' || c == ',' || c == '\'' || c == '"'
|| c == EOF);
}
static inline bool
LEXERisOperator (const char *name)
{
for (size_t i = 0; i < strlen (name); i++)
if (!is_operator_symbol (name[i]))
return false;
return true;
}
/* If the value of the token needs a character buffer or it is
stored as an enum token_kind variable. */
//__BEGIN_DECLS
bool lexer_init_file (struct lexer *, FILE *, const char *);
bool lexer_init (struct lexer *, const char *);
......@@ -296,4 +275,9 @@ bool is_normal_id (const char *);
bool is_operator (const char *);
//__END_DECLS
static inline bool
LEXERisOperator (const char *name)
{
return !is_normal_id (name);
}
#endif /* __LEX_H__ */
......@@ -307,25 +307,6 @@ assign_constructor (node *a, node *b)
#define handle_assign_list(parser) \
handle_generic_list (parser, handle_assign, assign_constructor)
/* Handle list of types. Here we de-reference the pointers
node* <--> ntype*, in order to use handle_generic_list routines. */
static node *
rettype_constructor (node *a, node *b)
{
/* FIXME types do not have location for the time
being, so we cannot set it here. */
return TBmakeRet ((ntype *)a, b);
}
static node *
__handle_type (struct parser *parser)
{
/* FIXME types do not have location for the time
being, so we cannot set it here. */
return (node *)handle_type (parser);
}
#define handle_rettype_list(parser) \
handle_generic_list (parser, __handle_type, rettype_constructor)
/* This function pushes back all the tokens that are in the token_buffer
of the parser back into the lexer. */
static void
......@@ -513,11 +494,13 @@ handle_type_subscript_expr (struct parser *parser)
t = TBmakeSpid (NULL, strdup ("*"));
else {
parser_unget (parser);
/* FIXME handle_expr might be an overkill here: as expr has
conditionals, binary operations, etc. */
t = handle_expr (parser);
}
if (t == error_mark_node) {
error_loc (token_location (tok), "invalid type dimension expression");
if (t == NULL || t == error_mark_node) {
error_loc (token_location (tok), "invalid or missing type dimension expression");
return error_mark_node;
}
......@@ -861,7 +844,6 @@ parser_init (struct parser *parser, struct lexer *lex)
parser->used_modules = NULL;
parser->in_return = false;
parser->in_rettypes = false;
parser->in_subscript = false;
parser->in_module = false;
parser->current_module = NULL;
......@@ -1878,7 +1860,8 @@ handle_primary_expr (struct parser *parser)
warning_loc (token_location (tok), "using deprecated type-cast "
"syntax, please remove the `:' character"); */
type = handle_type (parser);
if (error_type_node == (type = handle_type (parser)))
return error_mark_node;
if (!TYisAKS (type)) {
error_loc (loc, "Empty array with non-constant "
......@@ -3462,7 +3445,7 @@ handle_assign (struct parser *parser)
are allowed to act as expressions. */
else if ((!strcmp (SPID_NAME (SPAP_ID (lhs)), "++")
|| !strcmp (SPID_NAME (SPAP_ID (lhs)), "--"))
&& SPID_NS (SPAP_ID (lhs)) == NULL
&& SPID_NS (SPAP_ID (lhs)) == NULL && TCcountExprs (SPAP_ARGS (lhs)) == 1
&& NODE_TYPE (EXPRS_EXPR (SPAP_ARGS (lhs))) == N_spid) {
node *id = EXPRS_EXPR (SPAP_ARGS (lhs));
if (SPID_NS (id) != NULL) {
......@@ -4188,16 +4171,6 @@ handle_generic_list (struct parser *parser, node *(*handle) (struct parser *),
return constructor (res, NULL);
}
if (parser->in_rettypes) {
tok = parser_get_token (parser);
if (token_is_operator (tok, tv_threedots)) {
parser_unget (parser);
parser_unget (parser);
return constructor (res, NULL);
} else
parser_unget (parser);
}
t = handle_generic_list (parser, handle, constructor);
if (t == NULL || t == error_mark_node) {
error_loc (token_location (tok), "nothing follows the comma");
......@@ -4207,6 +4180,44 @@ handle_generic_list (struct parser *parser, node *(*handle) (struct parser *),
return constructor (res, t);
}
static node *
handle_rettype_list (struct parser *parser)
{
struct token *tok;
ntype *res = handle_type (parser);
node *t;
if (res == NULL)
return NULL;
if (res == error_type_node)
return error_mark_node;
tok = parser_get_token (parser);
if (!token_is_operator (tok, tv_comma)) {
parser_unget (parser);
return TBmakeRet (res, NULL);
}
/* Check if the next token is '...', in whcih case
we have reached the end of the list. If we don't have
this code, then the next recursive invocation will emit
an error. */
tok = parser_get_token (parser);
if (token_is_operator (tok, tv_threedots)) {
parser_unget2 (parser);
return TBmakeRet (res, NULL);
} else
parser_unget (parser);
t = handle_rettype_list (parser);
if (t == NULL || t == error_mark_node) {
error_loc (token_location (tok), "valid type expected after comma");
return error_mark_node;
}
return TBmakeRet (res, t);
}
/* rettypes ::= type-list | type-list ',' '...' | '...' */
node *
handle_rettypes (struct parser *parser, bool vaargs, bool *three_dots_p)
......@@ -4223,12 +4234,22 @@ handle_rettypes (struct parser *parser, bool vaargs, bool *three_dots_p)
parser_get_token (parser);
return NULL;
}
/* XXX decide whether we support just three dots without the first argument.
This used to be the case in the sac bison definition, but it contradicts
with the syntax specification. */
else if (token_is_operator (tok, tv_threedots)) {
parser_get_token (parser);
if (!vaargs) {
error_loc (token_location (tok), "... type is only allowed "
"for function declarations");
return error_mark_node;
} else {
*three_dots_p = true;
return NULL;
}
}
parser->in_rettypes = true;
ret = handle_rettype_list (parser);
parser->in_rettypes = false;
if (ret == error_mark_node)
if (error_mark_node == (ret = handle_rettype_list (parser)))
return ret;
if (ret != NULL && vaargs) {
......@@ -4241,12 +4262,6 @@ handle_rettypes (struct parser *parser, bool vaargs, bool *three_dots_p)
parser_unget (parser);
} else
parser_unget (parser);
} else {
tok = parser_get_token (parser);
if (token_is_operator (tok, tv_threedots))
*three_dots_p = true;
else
parser_unget (parser);
}
if (ret == NULL && !*three_dots_p)
......
......@@ -67,7 +67,6 @@ struct parser {
/* Context-dependend parser variables. */
bool in_return;
bool in_rettypes;
bool in_subscript;
/* In case we are parsing a module. */
......
......@@ -18,24 +18,9 @@
#include <stdarg.h>
#endif
/*
* bool values
*/
#ifdef __bool_true_false_are_defined
#undef bool
#undef true
#undef false
#endif /* __bool_true_false_are_defined */
#ifndef __cplusplus
typedef unsigned int bool;
#endif
#define FALSE 0
#define TRUE 1
#include <stdbool.h>
#define TRUE true
#define FALSE false
/* Structcure to store where a token came from. */
struct location {
......
......@@ -49,7 +49,7 @@ version="1.0">
<xsl:if test="sons/son[ not( @default)]" >
<xsl:value-of select="' ,'"/>
</xsl:if>
<xsl:value-of select="'char *file, int line)'"/>
<xsl:value-of select="'const char *file, int line)'"/>
</xsl:template>
......
......@@ -176,6 +176,12 @@ typedef enum {
#endif /* SAC_DO_TRACE_MT */
#if SAC_DO_TRACE_GPU
#define SAC_TR_GPU_PRINT(...) SAC_TR_PRINT (("GPU -> " __VA_ARGS__))
#else /* SAC_DO_TRACE_GPU */
#define SAC_TR_GPU_PRINT( ...)
#endif /* SAC_DO_TRACE_GPU */
#if SAC_DO_TRACE_DISTMEM
#define SAC_TR_DISTMEM_PRINT(...) SAC_TR_PRINT (("DSM -> " __VA_ARGS__))
......
# Make sure that we Have GTest, and add some boilerplate definitions.
FIND_PACKAGE (GTest REQUIRED)
INCLUDE_DIRECTORIES (${GTEST_INCLUDE_DIR})
# As we are going to interface libsac2c.so, we want to define all the
# include paths, to avoid writing function declarations manually.
FILE (GLOB_RECURSE headers ${PROJECT_SOURCE_DIR}/src/libsac2c/*.h)
SET (dirlist "")
FOREACH (hpath ${headers})
GET_FILENAME_COMPONENT (hdir ${hpath} PATH)
LIST (APPEND dirlist ${hdir})
ENDFOREACH ()
LIST (REMOVE_DUPLICATES dirlist)
# All the src/libsac2c subdirs that contain *.h
INCLUDE_DIRECTORIES (${dirlist})
# All the generated files
INCLUDE_DIRECTORIES (${PROJECT_BINARY_DIR}/src/libsac2c)
# Generated global files like config, fun-attrs, etc.
INCLUDE_DIRECTORIES (${PROJECT_BINARY_DIR}/src/include)
MACRO (ADD_FUNC_TEST BIN_NAME SRC_NAME)
# Compile the test
ADD_EXECUTABLE (${BIN_NAME} ${SRC_NAME})
# Link against Gtest
TARGET_LINK_LIBRARIES (${BIN_NAME} GTest::GTest GTest::Main sac2cShared)
# Make it a part of the global testsuite
# so that it is executed via ctests.
GTEST_ADD_TESTS (${BIN_NAME} "" AUTO) # maket it a part of ctest call
ENDMACRO ()
ADD_FUNC_TEST (string-tests string-tests.cpp)
ADD_FUNC_TEST (test-assoc-law test-assoc-law.cpp)
ADD_FUNC_TEST (test-icm-compilation test-icm-compilation.cpp)
// Some convenience macros.
#define make_vec_type(__x) TYmakeAKD (TYmakeSimpleType (__x), 1, SHmakeShape (0))
#define make_scalar_type(__x) TYmakeAKS (TYmakeSimpleType (__x), SHmakeShape (0))
#define int_akv_avis(__n, __v) TBmakeAvis (strdup (__n), \
TYmakeAKV (TYmakeSimpleType (T_int), COmakeConstantFromInt (__v)))
#define int_avis(__x) TBmakeAvis (strdup (__x), make_scalar_type (T_int))
#define int_vec_avis(__x) TBmakeAvis (strdup (__x), make_vec_type (T_int))
#define binary_prf(prf, arg1, arg2) \
TBmakePrf (prf, TBmakeExprs (arg1, TBmakeExprs (arg2, NULL)))
#define make_let(avis, rhs) TBmakeLet (TBmakeIds (avis, NULL), rhs)
#include <sys/types.h>
#include <dirent.h>
#include "gtest/gtest.h"
extern "C" {
#include "memory.h"
#include "str.h"
}
TEST (StringOperations, testToUpper)
{
char *t = strdup ("test");
STRtoupper (t, 0, 1);
EXPECT_STREQ ("Test", t);
STRtoupper (t, 0, 2);
EXPECT_STREQ ("TEst", t);
MEMfree (t);
}
// The code is total shite, it overruns the buffer
// FIXME This test shows a problem in the code. Fix it in str.c,
// uncomment the test and write a few more.
//TEST (StringOperations, testToUpperDoNotSegfault)
//{
// char *t = strdup ("test");
// EXPECT_NO_THROW (STRtoupper (t, 0, 1000000));
// EXPECT_STREQ ("TEST", t);
// MEMfree (t);
//}
TEST (StringOperations, testStrCpy)
{
char *t = STRcpy ("test");
EXPECT_STREQ ("test", t);
MEMfree (t);
char *tt = STRcpy (NULL);
EXPECT_EQ (tt, (void *)NULL);
}
TEST (StringOperations, testStrNCpy)
{
char *t = STRncpy ("test", 2);
EXPECT_STREQ ("te", t);
MEMfree (t);
}
// This code is shite too, as it declares the size as int and doesn't check
// for negative sizes.
//
// FIXME These tests demonstrates errors in the existing imdplementation of
// String functions. Adjust str.c, uncomment these, and write more.
//TEST (StringOperations, testStrNCpyDie)
//{
// ::testing::FLAGS_gtest_death_test_style = "threadsafe";
// char *tt;
// ASSERT_DEATH (tt = STRncpy ("test", -1), "Assertion");
//}
//
//// Again, what the hell we are supposed to do with negative lengths?
//TEST (StringOperations, testSubStr01)
//{
// char *t = STRsubStr ("test01", -1, 1);
// EXPECT_STREQ ("1", t);
// MEMfree (t);
//}
//
//
//TEST (StringOperations, testSubStr02)
//{
// char *t = STRsubStr ("test01", -10000, 1);
// EXPECT_STREQ ("t", t);
// MEMfree (t);
//}
TEST (StringOperations, testSubStr03)
{
char *t = STRsubStr ("test01", 1, 1);
EXPECT_STREQ ("e", t);
MEMfree (t);
}
TEST (StringOperations, testSubStr04)
{
char *t = STRsubStr ("test01", 100, 1);
EXPECT_STREQ ("", t);
MEMfree (t);
}
TEST (StringOperations, testSubStr05)
{
char *t = STRsubStr ("test01", 2, -100);
EXPECT_STREQ ("", t);
MEMfree (t);
}
#include "gtest/gtest.h"
#include <cstdlib>
extern "C" {
#include "options.h"
#include "types.h"
#include "new_types.h"
#include "shape.h"
#include "tree_basic.h"
#include "globals.h"
#include "associative_law.h"
#include "print.h"
#include "free.h"
#include "resource.h"
#include "sacdirs.h"
#define DBUG_PREFIX "AL-TEST"
#include "debug.h"
#include "constants.h"
#include "limits.h"
}
#include "macros.h"
static const char out[] =
"\n"
"/*-----------------------------------------------*/\n"
"{ \n"
" int[.] _al_4; \n"
" int _al_3; \n"
" int[.] _al_2; \n"
" int _al_1; \n"
" int{2} _al_0; \n"
"\n"
" o = 1; \n"
" x = _add_SxS_( a, o); \n"
" y = _add_VxS_( c, o); \n"
" z = _add_SxV_( b, d); \n"
" r = _add_SxV_( x, y); \n"
" _al_0 = _add_SxS_( o, o); \n"
" _al_1 = _add_SxS_( a, b); \n"
" _al_2 = _add_VxV_( c, d); \n"
" _al_3 = _add_SxS_( _al_0, _al_1); \n"
" _al_4 = _add_SxV_( _al_3, _al_2); \n"
" s = _al_4; \n"
" return( s); \n"
"}\n"
"/*-----------------------------------------------*/\n"
;
TEST (AssociativeLaw, test01)
{
// XXX(artem) This is how you can trigger debug output of
// a traversal. Can be very useful when writing
// tests, but not needed when we run the test.
//
//_db_on_ = 1;
//_db_push_ ("-#d,AL");
char **argv = (char **)malloc (sizeof (char *));
argv[0] = strdup ("test");
GLOBinitializeGlobal (1, argv, TOOL_sac2c, argv[0]);
// This is the program that we want to create and
// run AL on. This is a direct copy from the comments
// in AL.
//
// int[.] foo (int a, int b, int[.] c, int[.] d) {
// x = a _add_SxS_ 1;
// y = c _add_VxS_ 1;
// z = b _add_SxV_ d;
//
// r = x + y
// s = r + z
// return s;
// }
node *avis_a = int_avis ("a");
node *avis_b = int_avis ("b");
node *avis_c = int_vec_avis ("c");
node *avis_d = int_vec_avis ("d");
node *avis_x = int_avis ("x");
node *avis_y = int_vec_avis ("y");
node *avis_z = int_vec_avis ("z");
node *avis_s = int_vec_avis ("s");
node *avis_r = int_vec_avis ("r");
// This is the key to the optimisation, if it would have been of a
// normal akd type, this wouldn't work.
node *avis_o = int_akv_avis ("o", 1);
// Now we just compose block statements in the reverse order.
node * ret_stmt = TBmakeReturn (TBmakeExprs (TBmakeId (avis_s), NULL));
node * t = TBmakeAssign (ret_stmt, NULL);
node * s_let = make_let (avis_s, binary_prf (F_add_VxV, TBmakeId (avis_r), TBmakeId (avis_z)));
t = AVIS_SSAASSIGN (avis_s) = TBmakeAssign (s_let, t);
node * r_let = make_let (avis_r, binary_prf (F_add_SxV, TBmakeId (avis_x), TBmakeId (avis_y)));
t = AVIS_SSAASSIGN (avis_r) = TBmakeAssign (r_let, t);
node * z_let = make_let (avis_z, binary_prf (F_add_SxV, TBmakeId (avis_b), TBmakeId (avis_d)));
t = AVIS_SSAASSIGN (avis_z) = TBmakeAssign (z_let, t);