#!/bin/bash
#
# Copyright (C) 2008 Uday Bondhugula
# 
# Available under GNU GPL version 3 or (at your option) any later version
#
# Automatic annotation generation for unrolling
# Unroll/jammable loops are detected in the transformation
# framework. The purpose of the script is just to read the
# .unroll generated, generate and insert annotations that 
# will cause ancc to do the job.
#
# Don't bother to read anything below
#

match_closing_brace() {
    grep -n [{}] $1 > loopopenclose
    sed -n -e '/^'$2':/,$p' loopopenclose > cut

    open=0
    numclose=0
    while read -n1 char; do
        if [ "$char" == "{" ]; then
            open=$(($open+1))
        elif [ "$char" == "}" ]; then
            numclose=$(($numclose+1))
            open=$(($open-1))
            if [ $open == 0 ]; then
                break
            fi
        fi
    done <cut

    cat cut | grep "}" > closecut
    closing_brace_linenum=`sed -n -e ''$numclose'p' closecut | awk '{split($1,t,":"); print t[1]}'`
    rm -f cut loopopenclose closecut
    return $closing_brace_linenum
}

if [ ! -f .unroll ]; then
    exit 2
fi

numloops=`wc -l .unroll | awk '{print $1}'`

if [ $numloops == 0 ]; then
    exit 3
fi

# Generate the unrolling annotation 

# unroll only two

unrolldim1=`sed -n -e '1p' .unroll | awk '{print $1}'`
unrolldim2=`sed -n -e '2p' .unroll | awk '{print $1}'`

unrollcmd1=`sed -n -e '1p' .unroll | awk '{print $2}'`
unrollcmd2=`sed -n -e '2p' .unroll | awk '{print $2}'`

ufactor1=`sed -n -e '1p' .unroll | awk '{print $3}'`
ufactor2=`sed -n -e '2p' .unroll | awk '{print $3}'`

if [ $numloops -ne 1 ]; then
    # Find the unrollable hotspot with $unrolldim1 and $unrolldim2

    # 2 loops to unroll
    dirname=`dirname $1`

    params=""
    for i in `cat .params`; do params=$i\\\|$params; done
    params=$params"phony"

    num=""
    # don't even bother to ask what this is - the lowest levels I have stooped to
    for i in `grep -n  "for ($unrolldim1=" $1 | grep -v $params | awk '{split($1,t,":"); print t[1]}'`  ; do grep -n ".*" $1 |  sed -n -e \
        ''$(($i+1))'p'  | grep "for ($unrolldim2=" | grep -q -v "$params" ; if [ $? == "0" ]; then  num=$i; break; fi 
    done

    # if no loops with bounds free of parameters are found, just go for those
    # with params in them
    if [ "$num" == "" ]; then
        for i in `grep -n  "for ($unrolldim1=" $1 | awk '{split($1,t,":"); print t[1]}'` ; do grep -n ".*" $1 |  sed -n -e \
            ''$(($i+1))'p'  | grep "for ($unrolldim2=" | grep -q -v "$params" ; if [ $? == "0" ]; then  num=$i; break; fi 
        done

        # selling my soul to the devil now
        if [ "$num" == "" ]; then
            for i in `grep -n  "for ($unrolldim1=" $1 | awk '{split($1,t,":"); print t[1]}'` ; do grep -n ".*" $1 |  sed -n -e \
                ''$(($i+1))'p'  | grep -q "for ($unrolldim2=" ; if [ $? == "0" ]; then  num=$i; break; fi 
            done
        fi
    fi

    if [ "$num" == "" ]; then
        exit 4
    fi

    echo "[PLann] Found unrollable nest at $num of $1"
    #echo "[PLann] Found unrollable nest"
    match_closing_brace $1 $num
    annotation_end_line_num=$?

    sed -n -e '1,'$(($num-1))'p' $1 > .header
    echo "{" > .unrollbody
    sed -n -e ''$(($num+2))','$(($annotation_end_line_num-2))'p' $1 >> .unrollbody
    echo "}" >> .unrollbody
    #cat .unrollbody

    sed -n -e ''$num'p' $1 | tr -d "{" > .unroll1
    sed -n -e ''$(($num+1))'p' $1 | tr -d "{" > .unroll2

    echo "/*@ begin Loop(" > .annotation
    echo "transform $unrollcmd1(ufactor=$ufactor1)" >> .annotation
    cat .unroll1 >> .annotation
    echo "transform $unrollcmd2(ufactor=$ufactor2)" >> .annotation
    cat .unroll2 >> .annotation
    cat .unrollbody >> .annotation
    echo ") @*/" >> .annotation

    echo "/*@ end @*/" > .annotation_end

    sed -n -e ''$(($num+1))'p' $1 | tr -d "{" > .unroll2

    sed -n -e ''$num','$annotation_end_line_num'p' $1 > .middle
    sed -n -e ''$(($annotation_end_line_num+1))',$p' $1 > .footer

else
    # Only 1 loop to unroll
    dirname=`dirname $1`

    # Find the unrollable loop(s)
    params=""
    for i in `sed -n 1~2p .params`; do params=$i\\\|$params; done
    params=$params"phony"

    num=""
    # don't even bother to ask what this is - the lowest levels I have stooped to
    num=`grep -n  "for ($unrolldim1=" $1 | grep -v $params | awk '{split($1,t,":"); print t[1]}' | head -n 1`

    # if no loops with bounds free of parameters are found, just go for those
    # with params in them
    if [ "$num" == "" ]; then
        num=`grep -n  "for ($unrolldim1=" $1 | awk '{split($1,t,":"); print t[1]}'  | head -n 1`
    fi

    if [ "$num" == "" ]; then
        exit 4
    fi

    echo "[PLann] Found unrollable nest at line # $num" of $1
    match_closing_brace $1 $num
    annotation_end_line_num=$?

    sed -n -e '1,'$(($num-1))'p' $1 > .header
    echo "{" > .unrollbody
    sed -n -e ''$(($num+1))','$(($annotation_end_line_num-1))'p' $1 >> .unrollbody
    echo "}" >> .unrollbody
    #cat .unrollbody

    sed -n -e ''$num'p' $1 | tr -d "{" > .unroll1

    echo "/*@ begin Loop(" > .annotation
    echo "transform $unrollcmd1(ufactor=$ufactor1)" >> .annotation
    cat .unroll1 >> .annotation
    cat .unrollbody >> .annotation
    echo ") @*/" >> .annotation

    echo "/*@ end @*/" > .annotation_end

    sed -n -e ''$num','$annotation_end_line_num'p' $1 > .middle
    sed -n -e ''$(($annotation_end_line_num+1))',$p' $1 > .footer
fi

cat .header .annotation .middle .annotation_end .footer > $1

# run the annotation generator
export ANNOTATIONS_DIR=$2
ANCC="$ANNOTATIONS_DIR/bin/ancc"

$ANCC $1 $1.ancc
cp -f $1 .ancc
mv -f $1.ancc $1
echo "[PLann] Finished running ancc"

rm -f .header .lb .ub .header .footer .vecloop .middle .footer .annotation .annotation_end .unroll1 .unroll2 .unrollbody .ancc
exit 0
