#!/bin/bash
################################################################################
##
## The University of Illinois/NCSA
## Open Source License (NCSA)
##
## Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
##
## Developed by:
##
##                 AMD Research and AMD HSA Software Development
##
##                 Advanced Micro Devices, Inc.
##
##                 www.amd.com
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to
## deal with the Software without restriction, including without limitation
## the rights to use, copy, modify, merge, publish, distribute, sublicense,
## and#or sell copies of the Software, and to permit persons to whom the
## Software is furnished to do so, subject to the following conditions:
##
##  - Redistributions of source code must retain the above copyright notice,
##    this list of conditions and the following disclaimers.
##  - Redistributions in binary form must reproduce the above copyright
##    notice, this list of conditions and the following disclaimers in
##    the documentation and#or other materials provided with the distribution.
##  - Neither the names of Advanced Micro Devices, Inc,
##    nor the names of its contributors may be used to endorse or promote
##    products derived from this Software without specific prior written
##    permission.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
## DEALINGS WITH THE SOFTWARE.
##
################################################################################

set -e

CLANG_BIN=/opt/rocm/lib/llvm/bin
BITCODE_DIR=/opt/rocm/amdgcn/bitcode
OPENCL_INCLUDE=`echo | ${CLANG_BIN}/clang -v -x c++ -c - -o /dev/null |& grep clang | tail -n1`
CLANG=${CLANG_BIN}/clang
LLVM_LINK=${CLANG_BIN}/llvm-link

TRIPLE=amdgcn-amd-amdhsa

gfxip=803
codeobjver=4

while (( "$#" ))
do
    arg="$1"
    case "$arg" in
    -o)
        shift
        output_file=$1
        ;;
    -mcode-object-version=*)
        codeobjver=${1##*=}
        if [ "$codeobjver" -le 4 ]; then
            codeobjver=4
        fi
        options="${options} $1"
        ;;
    -mcpu=gfx*)
        gfxip=${1##*gfx}
        ;&
    [-\+]*)
        options="${options} $1"
        ;;
    *)
        input_file=$1
        ;;
    esac
    shift
done

# Support new device-lib suffix .bc
if [ -e $BITCODE_DIR/opencl.amdgcn.bc ]; then
    BC_SUFFIX="amdgcn.bc"
else
    BC_SUFFIX="bc"
fi

BITCODE_ARGS="$BITCODE_DIR/opencl.$BC_SUFFIX \
    $BITCODE_DIR/ocml.$BC_SUFFIX \
    $BITCODE_DIR/ockl.$BC_SUFFIX \
    $BITCODE_DIR/oclc_abi_version_${codeobjver}00.$BC_SUFFIX \
    $BITCODE_DIR/oclc_correctly_rounded_sqrt_off.$BC_SUFFIX \
    $BITCODE_DIR/oclc_daz_opt_on.$BC_SUFFIX \
    $BITCODE_DIR/oclc_finite_only_off.$BC_SUFFIX \
    $BITCODE_DIR/oclc_isa_version_${gfxip}.$BC_SUFFIX \
    $BITCODE_DIR/oclc_unsafe_math_off.$BC_SUFFIX"

${CLANG} -c -emit-llvm \
-target $TRIPLE -x cl \
-D__AMD__=1  \
-D__gfx${gfxip}__=1  \
-D__gfx${gfxip}=1  \
-D__OPENCL_VERSION__=120  \
-D__IMAGE_SUPPORT__=1 \
-O3 \
-m64 \
-cl-kernel-arg-info \
-nogpulib \
-cl-std=CL1.2 \
-mllvm -amdgpu-early-inline-all \
-Xclang -cl-ext=+cl_khr_fp64,+cl_khr_global_int32_base_atomics,+cl_khr_global_int32_extended_atomics,+cl_khr_local_int32_base_atomics,+cl_khr_local_int32_extended_atomics,+cl_khr_int64_base_atomics,+cl_khr_int64_extended_atomics,+cl_khr_3d_image_writes,+cl_khr_byte_addressable_store,+cl_khr_gl_sharing,+cl_amd_media_ops,+cl_amd_media_ops2,+cl_khr_subgroups \
-include ${OPENCL_INCLUDE}/opencl-c.h \
${options} -o ${output_file}.orig.bc ${input_file}

${LLVM_LINK} -f -o ${output_file}.linked.bc ${output_file}.orig.bc \
${BITCODE_ARGS} |& tee ${output_file}.linked.bc.out

# Fail on warnings
if grep -qi warning ${output_file}.linked.bc.out; then
    echo "llvm-link failed!"
    exit 1
fi

${CLANG} \
-target $TRIPLE \
-O3 \
-m64 \
-cl-kernel-arg-info \
-nogpulib \
-mllvm -amdgpu-internalize-symbols -mllvm -amdgpu-early-inline-all \
${options} -o ${output_file} ${output_file}.linked.bc

# Remove extra files
rm ${output_file}.linked.bc*
