Commit ae7d03ce authored by Torben Gerhards's avatar Torben Gerhards
Browse files

Implemented lifting of with-loops into SPMD-functions for the "new" mt and

implemented a facility which sets the correct linksigns for the SPMD-functions.
Showing with 506 additions and 16 deletions
+506 -16
#include "set_spmd_linksign.h"
#include "dbug.h"
#include "tree_basic.h"
#include "tree_compound.h"
#include "traverse.h"
#include "memory.h"
#include "LookUpTable.h"
/**
* INFO structure
*/
struct INFO {
node *with_rets;
node *fun_rets;
lut_t *lut;
int ls_num;
bool mem;
bool returns;
};
/**
* INFO macros
*/
#define INFO_WITH_RETS(n) (n->with_rets)
#define INFO_FUN_RETS(n) (n->fun_rets)
#define INFO_LUT(n) (n->lut)
#define INFO_LS_NUM(n) (n->ls_num)
#define INFO_MEM(n) (n->mem)
#define INFO_RETURNS(n) (n->returns)
/**
* INFO functions
*/
static info *
MakeInfo ()
{
DBUG_ENTER ("MakeInfo");
info *result;
result = MEMmalloc (sizeof (info));
INFO_WITH_RETS (result) = NULL;
INFO_FUN_RETS (result) = NULL;
INFO_LUT (result) = NULL;
INFO_LS_NUM (result) = 0;
INFO_MEM (result) = FALSE;
INFO_RETURNS (result) = FALSE;
DBUG_RETURN (result);
}
static info *
FreeInfo (info *info)
{
DBUG_ENTER ("FreeInfo");
info = MEMfree (info);
DBUG_RETURN (info);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSarg (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSarg");
node *nret = NULL;
nret = LUTsearchInLutPp (INFO_LUT (arg_info), ARG_AVIS (arg_node));
if (nret != ARG_AVIS (arg_node)) {
ARG_LINKSIGN (arg_node) = RET_LINKSIGN (nret);
} else {
ARG_LINKSIGN (arg_node) = INFO_LS_NUM (arg_info);
INFO_LS_NUM (arg_info) += 1;
}
ARG_HASLINKSIGNINFO (arg_node) = TRUE;
DBUG_PRINT ("SSPMDLS",
("Add LS %i to arg %s", ARG_LINKSIGN (arg_node), ARG_NAME (arg_node)));
if (ARG_NEXT (arg_node) != NULL) {
ARG_NEXT (arg_node) = TRAVdo (ARG_NEXT (arg_node), arg_info);
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSid (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSid");
if (INFO_MEM (arg_info)) {
INFO_LUT (arg_info)
= LUTinsertIntoLutP (INFO_LUT (arg_info), IDS_AVIS (INFO_WITH_RETS (arg_info)),
ID_AVIS (arg_node));
} else if (INFO_RETURNS (arg_info)) {
node *avis = NULL;
avis = LUTsearchInLutPp (INFO_LUT (arg_info), ID_AVIS (arg_node));
INFO_LUT (arg_info)
= LUTinsertIntoLutP (INFO_LUT (arg_info), avis, INFO_FUN_RETS (arg_info));
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSexprs (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSexprs");
if (INFO_RETURNS (arg_info)) {
EXPRS_EXPR (arg_node) = TRAVdo (EXPRS_EXPR (arg_node), arg_info);
if (EXPRS_NEXT (arg_node) != NULL) {
INFO_FUN_RETS (arg_info) = RET_NEXT (INFO_FUN_RETS (arg_info));
DBUG_ASSERT (INFO_FUN_RETS (arg_info) != NULL, "#Returns != #Rets!");
EXPRS_NEXT (arg_node) = TRAVdo (EXPRS_NEXT (arg_node), arg_info);
}
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSreturn (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSreturn");
INFO_RETURNS (arg_info) = TRUE;
RETURN_EXPRS (arg_node) = TRAVdo (RETURN_EXPRS (arg_node), arg_info);
INFO_RETURNS (arg_info) = FALSE;
INFO_FUN_RETS (arg_info) = NULL;
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSgenarray (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSgenarray");
INFO_MEM (arg_info) = TRUE;
GENARRAY_MEM (arg_node) = TRAVdo (GENARRAY_MEM (arg_node), arg_info);
INFO_MEM (arg_info) = FALSE;
if (GENARRAY_NEXT (arg_node) != NULL) {
INFO_WITH_RETS (arg_info) = IDS_NEXT (INFO_WITH_RETS (arg_info));
DBUG_ASSERT (INFO_WITH_RETS (arg_info) != NULL, "#ids != #with-returns!");
GENARRAY_NEXT (arg_node) = TRAVdo (GENARRAY_NEXT (arg_node), arg_info);
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSmodarray (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSmodarray");
INFO_MEM (arg_info) = TRUE;
MODARRAY_MEM (arg_node) = TRAVdo (MODARRAY_MEM (arg_node), arg_info);
INFO_MEM (arg_info) = FALSE;
if (MODARRAY_NEXT (arg_node) != NULL) {
INFO_WITH_RETS (arg_info) = IDS_NEXT (INFO_WITH_RETS (arg_info));
DBUG_ASSERT (INFO_WITH_RETS (arg_info) != NULL, "#ids != #with-returns!");
MODARRAY_NEXT (arg_node) = TRAVdo (MODARRAY_NEXT (arg_node), arg_info);
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSbreak (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSbreak");
INFO_MEM (arg_info) = TRUE;
BREAK_MEM (arg_node) = TRAVdo (BREAK_MEM (arg_node), arg_info);
INFO_MEM (arg_info) = FALSE;
if (BREAK_NEXT (arg_node) != NULL) {
INFO_WITH_RETS (arg_info) = IDS_NEXT (INFO_WITH_RETS (arg_info));
DBUG_ASSERT (INFO_WITH_RETS (arg_info) != NULL, "#ids != #with-returns!");
BREAK_NEXT (arg_node) = TRAVdo (BREAK_NEXT (arg_node), arg_info);
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSwith2 (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSwith2");
/* We just have to traverse the withops*/
WITH2_WITHOP (arg_node) = TRAVdo (WITH2_WITHOP (arg_node), arg_info);
INFO_WITH_RETS (arg_info) = NULL;
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSlet (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSlet");
/* Keep LHS, if RHS is withloop, it is needed.*/
INFO_WITH_RETS (arg_info) = LET_IDS (arg_node);
LET_EXPR (arg_node) = TRAVdo (LET_EXPR (arg_node), arg_info);
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSret (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSret");
if (INFO_LS_NUM (arg_info) > 0) {
/* Set linksign*/
RET_LINKSIGN (arg_node) = INFO_LS_NUM (arg_info);
RET_HASLINKSIGNINFO (arg_node) = TRUE;
DBUG_PRINT ("SSPMDLS", ("Add LS %i to ret", RET_LINKSIGN (arg_node)));
INFO_LS_NUM (arg_info) += 1;
if (RET_NEXT (arg_node) != NULL) {
RET_NEXT (arg_node) = TRAVdo (RET_NEXT (arg_node), arg_info);
}
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSfundef (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLSfundef");
if (FUNDEF_ISSPMDFUN (arg_node)) {
INFO_LS_NUM (arg_info) = 1;
/* First of all, add LS to rets*/
FUNDEF_RETS (arg_node) = TRAVdo (FUNDEF_RETS (arg_node), arg_info);
/* Keep rets to link them to the arguments*/
INFO_FUN_RETS (arg_info) = FUNDEF_RETS (arg_node);
/* Traverse through the body to link the rets to the args*/
FUNDEF_BODY (arg_node) = TRAVdo (FUNDEF_BODY (arg_node), arg_info);
/* Traverse the args to add the LS*/
FUNDEF_ARGS (arg_node) = TRAVdo (FUNDEF_ARGS (arg_node), arg_info);
INFO_LS_NUM (arg_info) = 0;
}
INFO_LUT (arg_info) = LUTremoveContentLut (INFO_LUT (arg_info));
if (FUNDEF_NEXT (arg_node) != NULL) {
FUNDEF_NEXT (arg_node) = TRAVdo (FUNDEF_NEXT (arg_node), arg_info);
}
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param arg_node
* @param arg_info
*
* @return
******************************************************************************/
node *
SSPMDLSmodule (node *arg_node, info *arg_info)
{
DBUG_ENTER ("SSPMDLmodule");
INFO_LUT (arg_info) = LUTgenerateLut ();
if (MODULE_FUNS (arg_node) != NULL) {
MODULE_FUNS (arg_node) = TRAVdo (MODULE_FUNS (arg_node), arg_info);
}
INFO_LUT (arg_info) = LUTremoveLut (INFO_LUT (arg_info));
DBUG_RETURN (arg_node);
}
/** <!-- ****************************************************************** -->
* @brief
*
* @param syntax_tree
*
* @return
******************************************************************************/
node *
SSPMDLSdoSetSpmdLinksign (node *syntax_tree)
{
DBUG_ENTER ("SSPMDLSdoSetSpmdLinksign");
info *info;
info = MakeInfo ();
TRAVpush (TR_sspmdls);
syntax_tree = TRAVdo (syntax_tree, info);
TRAVpop ();
info = FreeInfo (info);
DBUG_RETURN (syntax_tree);
}
#ifndef _SET_SPMD_LINKSIGN_H_
#define _SET_SPMD_LINKSIGN_H_
#include "types.h"
extern node *SSPMDLSarg (node *arg_node, info *arg_info);
extern node *SSPMDLSid (node *arg_node, info *arg_info);
extern node *SSPMDLSexprs (node *arg_node, info *arg_info);
extern node *SSPMDLSreturn (node *arg_node, info *arg_info);
extern node *SSPMDLSgenarray (node *arg_node, info *arg_info);
extern node *SSPMDLSmodarray (node *arg_node, info *arg_info);
extern node *SSPMDLSbreak (node *arg_node, info *arg_info);
extern node *SSPMDLSwith2 (node *arg_node, info *arg_info);
extern node *SSPMDLSlet (node *arg_node, info *arg_info);
extern node *SSPMDLSret (node *arg_node, info *arg_info);
extern node *SSPMDLSfundef (node *arg_node, info *arg_info);
extern node *SSPMDLSmodule (node *arg_node, info *arg_info);
extern node *SSPMDLSdoSetSpmdLinksign (node *syntax_tree);
#endif /* _SET_SPMD_LINKSIGN_H_*/
......@@ -417,19 +417,25 @@ SPMDLid (node *arg_node, info *arg_info)
DBUG_PRINT ("SPMDL", ("ENTER id %s", ID_NAME (arg_node)));
if (INFO_COLLECT (arg_info)) {
if (LUTsearchInLutPp (INFO_LUT (arg_info), arg_node) == arg_node) {
if (LUTsearchInLutPp (INFO_LUT (arg_info), avis) == avis) {
DBUG_PRINT ("SPMDL", (" Not handled before..."));
new_avis = DUPdoDupNode (avis);
INFO_ARGS (arg_info) = TBmakeArg (new_avis, INFO_ARGS (arg_info));
INFO_PARAMS (arg_info)
= TBmakeExprs (TBmakeId (avis), INFO_PARAMS (arg_info));
if (!INFO_WITHID (arg_info)) {
INFO_ARGS (arg_info) = TBmakeArg (new_avis, INFO_ARGS (arg_info));
INFO_PARAMS (arg_info)
= TBmakeExprs (TBmakeId (avis), INFO_PARAMS (arg_info));
}
INFO_LUT (arg_info) = LUTinsertIntoLutP (INFO_LUT (arg_info), avis, new_avis);
}
if (INFO_WITHID (arg_info)) {
DBUG_PRINT ("SPMDL", ("...is Withid-id"));
if (new_avis == NULL) {
new_avis = LUTsearchInLutPp (INFO_LUT (arg_info), arg_node);
new_avis = LUTsearchInLutPp (INFO_LUT (arg_info), avis);
} else {
INFO_VARDECS (arg_info)
= TBmakeVardec (new_avis, INFO_VARDECS (arg_info));
}
/*Mem*/
/*Build memory allocation for withid*/
......@@ -479,18 +485,24 @@ SPMDLids (node *arg_node, info *arg_info)
node *avis = IDS_AVIS (arg_node);
node *new_avis = NULL;
DBUG_PRINT ("SPMDL", ("ENTER ids %s", IDS_NAME (arg_node)));
if (INFO_COLLECT (arg_info)) {
if (LUTsearchInLutPp (INFO_LUT (arg_info), arg_node) == NULL) {
if (LUTsearchInLutPp (INFO_LUT (arg_info), avis) == avis) {
new_avis = DUPdoDupNode (avis);
INFO_VARDECS (arg_info) = TBmakeVardec (new_avis, INFO_VARDECS (arg_info));
INFO_LUT (arg_info) = LUTinsertIntoLutP (INFO_LUT (arg_info), avis, new_avis);
DBUG_PRINT ("SPMDL", (">>> ids %s added to LUT", IDS_NAME (arg_node)));
}
} else {
/* If INFO_LIFT is true, we are on the LHS of the assignment which has the
* MT-Withloop on the RHS.*/
if (INFO_LIFT (arg_info)) {
new_avis = DUPdoDupNode (avis);
INFO_ARGS (arg_info) = TBmakeArg (new_avis, INFO_ARGS (arg_info));
INFO_LUT (arg_info) = LUTinsertIntoLutP (INFO_LUT (arg_info), avis, new_avis);
/*
INFO_ARGS(arg_info) = TBmakeArg(new_avis, INFO_ARGS(arg_info));
*/
INFO_RETS (arg_info)
= TBmakeRet (TYeliminateAKV (AVIS_TYPE (new_avis)), INFO_RETS (arg_info));
......@@ -500,9 +512,11 @@ SPMDLids (node *arg_node, info *arg_info)
INFO_RETTYPES (arg_info)
= TCappendTypes (TYtype2OldType (AVIS_TYPE (new_avis)),
INFO_RETTYPES (arg_info));
INFO_PARAMS (arg_info)
= TBmakeExprs (TBmakeId (avis), INFO_PARAMS (arg_info));
/*
INFO_PARAMS(arg_info) = TBmakeExprs(TBmakeId(avis),
INFO_PARAMS(arg_info));
*/
INFO_VARDECS (arg_info) = TBmakeVardec (new_avis, INFO_VARDECS (arg_info));
}
}
......
......@@ -744,6 +744,12 @@ SUBPHASE (cmtf, "Creating MT variants of exported and provided functions",
SUBPHASE (spmdl, "Lifting SPMD blocks to functions", SPMDLdoSpmdLift,
(global.mtmode == MT_createjoin) || (global.mtmode == MT_startstop), pc)
SUBPHASE (sched, "Annotating scheduling informations", SCHEDdoScheduleTrav,
(global.mtmode == MT_createjoin) || (global.mtmode == MT_startstop), pc)
SUBPHASE (sspmdls, "Applying SPMD linksign pragma", SSPMDLSdoSetSpmdLinksign,
(global.mtmode == MT_createjoin) || (global.mtmode == MT_startstop), pc)
#endif /* BEMT */
SUBPHASE (sls, "Applying linksign pragma", SLSdoSetLinksign, ALWAYS, pc)
......
......@@ -1930,7 +1930,8 @@ PRTblock (node *arg_node, info *arg_info)
("Indentation unbalanced while printing function '%s`.\n"
" Indentation at beginning of function: %i.\n"
" Indentation at end of function: %i\n",
FUNDEF_NAME (arg_node), old_indent, global.indent));
FUNDEF_NAME (INFO_FUNDEF (arg_info)), old_indent,
global.indent));
}
}
......
......@@ -1975,6 +1975,23 @@
<node name="WLseg" />
</travuser>
</traversal>
<traversal id="SSPMDLS" name="Set SPMD linksign" default="sons" include="set_spmd_linksign.h">
<travuser>
<node name="Arg" />
<node name="Id" />
<node name="Exprs" />
<node name="Return" />
<node name="Genarray" />
<node name="Modarray" />
<node name="Break" />
<node name="With2" />
<node name="Let" />
<node name="Ret" />
<node name="Fundef" />
<node name="Module" />
</travuser>
</traversal>
<!--
<traversal id="RMSPMD" name="Remove Spmd blocks traversal" default="sons" include="removespmd.h">
<travuser>
<node name="Module" />
......@@ -1983,7 +2000,7 @@
<node name="Spmd" />
</travuser>
</traversal>
-->
<traversal id="TEM" name="Tag Executionmode" default="sons" include="tag_executionmode.h">
<travuser>
<node name="Ap" />
......
......@@ -161,8 +161,8 @@ libsac2c_arrayopt := ive_split_selections ive_reusewl_and_scalarize \
libsac2c_wltransform := wlpragma_funs wltransform wlidxs
libsac2c_concurrent := create_mtfuns spmd_init spmd_lift schedule \
removespmd
libsac2c_concurrent := create_mtfuns spmd_init spmd_lift \
schedule set_spmd_linksign #removespmd
libsac2c_multithread := multithread_lib tag_executionmode \
propagate_executionmode create_cells \
......
......@@ -12,7 +12,7 @@
include(`icm.m4')
#ifdef _SAC_MT_GEN_H_
#ifndef _SAC_MT_GEN_H_
#define _SAC_MT_GEN_H_
#ifndef SAC_SIMD_COMPILATION
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment