<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/pm/p10_update_ec_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2022                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file  p10_update_ec_state.C
/// @brief Update the core configured data in CCSR register and then deals with
///        deconfigured cores to verify the chiplet state..if it is still running then
///        will put the core to stop 11 state
///
/// *HWP HW Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner        : Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team            : PM
/// *HWP Level           : 2
/// *HWP Consumed by     : HB,PGPE,CME,OCC
///

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include "p10_update_ec_state.H"
#include <p10_pm_util.H>
#include "p10_hcd_common.H"
#include "p10_hcd_cache_stopclocks.H"
#include "p10_hcd_core_poweroff.H"
#include "p10_hcd_l3_purge.H"
#include "p10_hcd_l2_purge.H"
#include "p10_hcd_powerbus_purge.H"
#include "p10_hcd_l2_tlbie_quiesce.H"
#include "p10_hcd_ncu_purge.H"
#include "p10_hcd_chtm_purge.H"
#include "p10_hcd_core_stopclocks.H"
#include "p10_hcd_cache_poweroff.H"
#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_core_stopgrid.H"
#include <p10_scom_proc.H>
#include <p10_scom_c.H>
#include <p10_scom_eq.H>

using namespace scomt;
using namespace proc;
using namespace c;
using namespace eq;

// -----------------------------------------------------------------------------
//  Function prototypes
// -----------------------------------------------------------------------------
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos);

// -----------------------------------------------------------------------------
//  Constants
// -----------------------------------------------------------------------------

// See .H for documentation
fapi2::ReturnCode p10_update_ec_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    FAPI_IMP("> p10_update_ec_state");

    FAPI_TRY(update_ec_config(i_target),
             "Error update_core_config detected");
    //TODO Need to find the right way to get deconfigured target
    FAPI_TRY(verify_ec_hw_state(i_target));

fapi_try_exit:
    FAPI_INF("< p10_update_ec_state");

    return fapi2::current_err;
} // END p10_update_ec_state

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF (">>verify_hw_state");
    uint8_t l_core_unit_pos;

    std::vector<fapi2::Target<fapi2::TARGET_TYPE_CORE> >l_core_list;
    FAPI_TRY(getDeconfiguredTargets(i_target, l_core_list));

    for (auto l_core : l_core_list)
    {

        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                l_core,
                                l_core_unit_pos));
        FAPI_INF("Core present but non functional %d",
                 l_core_unit_pos);

        //Check the clock state and power state
        FAPI_TRY(p10_check_core_l3_clock_power_state(l_core, l_core_unit_pos));

    }

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

/// @brief Update the CCSR for cores
///
/// @param[in]     i_target   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("> update_core_config...");

    uint8_t l_present_core_unit_pos;
    uint8_t l_functional_core_unit_pos;
    fapi2::buffer<uint64_t> l_core_config = 0;
    fapi2::buffer<uint64_t> l_pscom_config = 0;

    auto l_core_present_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_PRESENT);

    auto l_core_functional_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_FUNCTIONAL);

    FAPI_INF("  Number of present cores = %d; Number of functional cores = %d",
             l_core_present_vector.size(),
             l_core_functional_vector.size());

    // For each present core,  set multicast groups and the CCSR
    for (auto core_present_it : l_core_present_vector)
    {
        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                core_present_it,
                                l_present_core_unit_pos));

        FAPI_INF("  Checking if present EC %d is functional",
                 l_present_core_unit_pos);

        for (auto core_functional_it : l_core_functional_vector)
        {
            FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                    core_functional_it,
                                    l_functional_core_unit_pos));
            FAPI_DBG("  Functional EC %d",
                     l_functional_core_unit_pos);

            if (l_functional_core_unit_pos == l_present_core_unit_pos)
            {
                // Set the appropriate bit in the Core Configuration Status
                // Register buffer
                FAPI_INF("  Setting EC %d as good in value to be written to CCSR",
                         l_present_core_unit_pos);
                l_core_config.setBit(l_present_core_unit_pos);

                auto l_eq = core_functional_it.getParent<fapi2::TARGET_TYPE_EQ>();

                l_present_core_unit_pos = l_present_core_unit_pos % 4;

                //Update the pscom enable bit
                l_pscom_config.setBit(l_present_core_unit_pos + 5);

                FAPI_TRY(fapi2::putScom(l_eq, CPLT_CTRL3_WO_OR, l_pscom_config));
                break;
            }  // Current core
        } // Functional core loop
    }  // Present core loop

    // Write the recalculated OCC Core Configuration Status Register
    FAPI_INF("  Writing OCC CCSR");
    FAPI_TRY(fapi2::putScom(i_target, TP_TPCHIP_OCC_OCI_OCB_CCSR_RW, l_core_config));

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

#define CORE_START_POSITION 5
#define CACHE_START_POSITION 9

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos)
{
    fapi2::buffer<uint64_t> l_data = 0;
    uint64_t l_pfet_sense = 0;
    uint8_t l_core_relative_pos  = i_core_unit_pos % 4;
    uint8_t l_l3_relative_pos    = i_core_unit_pos % 4;
    uint8_t l_core_clock_State = 0;
    uint8_t l_l3_clock_State = 0;

    do
    {
        auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();
        //Read the power state of core/l2
        FAPI_TRY(GET_CPMS_CL2_PFETSTAT(i_core_target, l_data));
        GET_CPMS_CL2_PFETSTAT_VDD_PFETS_ENABLED_SENSE(l_data, l_pfet_sense);

        //verify L3/core clocks are on
        FAPI_TRY(GET_CLOCK_STAT_SL(l_eq_target, l_data));
        l_core_clock_State = l_data & BIT64(l_core_relative_pos + CORE_START_POSITION);
        l_l3_clock_State   = l_data & BIT64(l_l3_relative_pos + CACHE_START_POSITION);

        //Verify core is powered on
        //If core is powered on
        //  then if core(ECl2) clocks are on
        //      then need to purge the l2 and stop the core clocks
        //  if L3 clocks are on
        //      then purge L3 and stop the l3 clocks
        //  Power off the core and L3
        if( l_pfet_sense)
        {
            if (!l_core_clock_State)
            {
                FAPI_TRY(p10_hcd_l2_purge(i_core_target));
                FAPI_TRY(p10_hcd_l2_tlbie_quiesce(i_core_target));
                FAPI_TRY(p10_hcd_ncu_purge(i_core_target));
                FAPI_TRY(p10_hcd_core_shadows_disable(i_core_target));
                FAPI_TRY(p10_hcd_core_stopclocks(i_core_target));
                FAPI_TRY(p10_hcd_core_stopgrid(i_core_target));
            }

            FAPI_TRY(p10_hcd_core_poweroff(i_core_target));

            if (!l_l3_clock_State)
            {
                FAPI_TRY(p10_hcd_chtm_purge(i_core_target));
                FAPI_TRY(p10_hcd_l3_purge(i_core_target));
                FAPI_TRY(p10_hcd_powerbus_purge(i_core_target));
                FAPI_TRY(p10_hcd_cache_stopclocks(i_core_target));
            }

            FAPI_TRY(p10_hcd_cache_poweroff(i_core_target));
        }
    }
    while(0);

fapi_try_exit:
    FAPI_INF("< p10_check_core_clock_power_state...");
    return fapi2::current_err;

}
<commit_msg>p10_update_ec_state - bypass deconfigured PFET check for now<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/pm/p10_update_ec_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2022                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file  p10_update_ec_state.C
/// @brief Update the core configured data in CCSR register and then deals with
///        deconfigured cores to verify the chiplet state..if it is still running then
///        will put the core to stop 11 state
///
/// *HWP HW Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner        : Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team            : PM
/// *HWP Level           : 2
/// *HWP Consumed by     : HB,PGPE,CME,OCC
///

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include "p10_update_ec_state.H"
#include <p10_pm_util.H>
#include "p10_hcd_common.H"
#include "p10_hcd_cache_stopclocks.H"
#include "p10_hcd_core_poweroff.H"
#include "p10_hcd_l3_purge.H"
#include "p10_hcd_l2_purge.H"
#include "p10_hcd_powerbus_purge.H"
#include "p10_hcd_l2_tlbie_quiesce.H"
#include "p10_hcd_ncu_purge.H"
#include "p10_hcd_chtm_purge.H"
#include "p10_hcd_core_stopclocks.H"
#include "p10_hcd_cache_poweroff.H"
#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_core_stopgrid.H"
#include <p10_scom_proc.H>
#include <p10_scom_c.H>
#include <p10_scom_eq.H>

using namespace scomt;
using namespace proc;
using namespace c;
using namespace eq;

// -----------------------------------------------------------------------------
//  Function prototypes
// -----------------------------------------------------------------------------
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos);

// -----------------------------------------------------------------------------
//  Constants
// -----------------------------------------------------------------------------

// See .H for documentation
fapi2::ReturnCode p10_update_ec_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    FAPI_IMP("> p10_update_ec_state");

    FAPI_TRY(update_ec_config(i_target),
             "Error update_core_config detected");
    //TODO Need to find the right way to get deconfigured target
    FAPI_TRY(verify_ec_hw_state(i_target));

fapi_try_exit:
    FAPI_INF("< p10_update_ec_state");

    return fapi2::current_err;
} // END p10_update_ec_state

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF (">>verify_hw_state");
    uint8_t l_core_unit_pos;

    std::vector<fapi2::Target<fapi2::TARGET_TYPE_CORE> >l_core_list;
    FAPI_TRY(getDeconfiguredTargets(i_target, l_core_list));

    for (auto l_core : l_core_list)
    {

        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                l_core,
                                l_core_unit_pos));
        FAPI_INF("Core present but non functional %d",
                 l_core_unit_pos);

        //Check the clock state and power state
// RTC 249759: temporarily enable deconfigured cores/L3 to check for PFET state
//        FAPI_TRY(p10_check_core_l3_clock_power_state(l_core, l_core_unit_pos));

    }

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

/// @brief Update the CCSR for cores
///
/// @param[in]     i_target   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("> update_core_config...");

    uint8_t l_present_core_unit_pos;
    uint8_t l_functional_core_unit_pos;
    fapi2::buffer<uint64_t> l_core_config = 0;
    fapi2::buffer<uint64_t> l_pscom_config = 0;

    auto l_core_present_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_PRESENT);

    auto l_core_functional_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_FUNCTIONAL);

    FAPI_INF("  Number of present cores = %d; Number of functional cores = %d",
             l_core_present_vector.size(),
             l_core_functional_vector.size());

    // For each present core,  set multicast groups and the CCSR
    for (auto core_present_it : l_core_present_vector)
    {
        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                core_present_it,
                                l_present_core_unit_pos));

        FAPI_INF("  Checking if present EC %d is functional",
                 l_present_core_unit_pos);

        for (auto core_functional_it : l_core_functional_vector)
        {
            FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                    core_functional_it,
                                    l_functional_core_unit_pos));
            FAPI_DBG("  Functional EC %d",
                     l_functional_core_unit_pos);

            if (l_functional_core_unit_pos == l_present_core_unit_pos)
            {
                // Set the appropriate bit in the Core Configuration Status
                // Register buffer
                FAPI_INF("  Setting EC %d as good in value to be written to CCSR",
                         l_present_core_unit_pos);
                l_core_config.setBit(l_present_core_unit_pos);

                auto l_eq = core_functional_it.getParent<fapi2::TARGET_TYPE_EQ>();

                l_present_core_unit_pos = l_present_core_unit_pos % 4;

                //Update the pscom enable bit
                l_pscom_config.setBit(l_present_core_unit_pos + 5);

                FAPI_TRY(fapi2::putScom(l_eq, CPLT_CTRL3_WO_OR, l_pscom_config));
                break;
            }  // Current core
        } // Functional core loop
    }  // Present core loop

    // Write the recalculated OCC Core Configuration Status Register
    FAPI_INF("  Writing OCC CCSR");
    FAPI_TRY(fapi2::putScom(i_target, TP_TPCHIP_OCC_OCI_OCB_CCSR_RW, l_core_config));

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

#define CORE_START_POSITION 5
#define CACHE_START_POSITION 9

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos)
{
    fapi2::buffer<uint64_t> l_data = 0;
    uint64_t l_pfet_sense = 0;
    uint8_t l_core_relative_pos  = i_core_unit_pos % 4;
    uint8_t l_l3_relative_pos    = i_core_unit_pos % 4;
    uint8_t l_core_clock_State = 0;
    uint8_t l_l3_clock_State = 0;

    do
    {
        auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();
        //Read the power state of core/l2
        FAPI_TRY(GET_CPMS_CL2_PFETSTAT(i_core_target, l_data));
        GET_CPMS_CL2_PFETSTAT_VDD_PFETS_ENABLED_SENSE(l_data, l_pfet_sense);

        //verify L3/core clocks are on
        FAPI_TRY(GET_CLOCK_STAT_SL(l_eq_target, l_data));
        l_core_clock_State = l_data & BIT64(l_core_relative_pos + CORE_START_POSITION);
        l_l3_clock_State   = l_data & BIT64(l_l3_relative_pos + CACHE_START_POSITION);

        //Verify core is powered on
        //If core is powered on
        //  then if core(ECl2) clocks are on
        //      then need to purge the l2 and stop the core clocks
        //  if L3 clocks are on
        //      then purge L3 and stop the l3 clocks
        //  Power off the core and L3
        if( l_pfet_sense)
        {
            if (!l_core_clock_State)
            {
                FAPI_TRY(p10_hcd_l2_purge(i_core_target));
                FAPI_TRY(p10_hcd_l2_tlbie_quiesce(i_core_target));
                FAPI_TRY(p10_hcd_ncu_purge(i_core_target));
                FAPI_TRY(p10_hcd_core_shadows_disable(i_core_target));
                FAPI_TRY(p10_hcd_core_stopclocks(i_core_target));
                FAPI_TRY(p10_hcd_core_stopgrid(i_core_target));
            }

            FAPI_TRY(p10_hcd_core_poweroff(i_core_target));

            if (!l_l3_clock_State)
            {
                FAPI_TRY(p10_hcd_chtm_purge(i_core_target));
                FAPI_TRY(p10_hcd_l3_purge(i_core_target));
                FAPI_TRY(p10_hcd_powerbus_purge(i_core_target));
                FAPI_TRY(p10_hcd_cache_stopclocks(i_core_target));
            }

            FAPI_TRY(p10_hcd_cache_poweroff(i_core_target));
        }
    }
    while(0);

fapi_try_exit:
    FAPI_INF("< p10_check_core_clock_power_state...");
    return fapi2::current_err;

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mutex.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 04:12:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    private:
        ResettableGuard(ResettableGuard &); // not defined
        void operator =(ResettableGuard &); // not defined

    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT_ ) :
                ClearableGuard<T>( pT_ ),
                pResetT( pT_ )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<commit_msg>INTEGRATION: CWS changefileheader (1.13.268); FILE MERGED 2008/03/31 13:23:36 rt 1.13.268.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: mutex.hxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    private:
        ResettableGuard(ResettableGuard &); // not defined
        void operator =(ResettableGuard &); // not defined

    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT_ ) :
                ClearableGuard<T>( pT_ ),
                pResetT( pT_ )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2021 Intel Corporation. All Rights Reserved.

#include <iostream>
#include <string>
#include <string.h> // memcpy
#include <fstream>
#include <vector>

#include "tclap/CmdLine.h"
#include <lz4.h>

#define STB_IMAGE_IMPLEMENTATION
#include "../third-party/stb_image.h"

#define RS_EMBED_VERSION "0.0.0.1"

struct float3
{
    float x, y, z;
};

struct short3
{
    uint16_t x, y, z;
};

using namespace std;
using namespace TCLAP;

bool file_exists(const std::string& name) {
    std::ifstream f(name.c_str());
    return f.good();
}

struct int6
{
    int x, y, z, a, b, c;
};

bool ends_with(const std::string& s, const std::string& suffix)
{
    auto i = s.rbegin(), j = suffix.rbegin();
    for (; i != s.rend() && j != suffix.rend() && *i == *j;
        i++, j++);
    return j == suffix.rend();
}

std::string get_current_time()
{
    auto t = time(nullptr);
    char buffer[20] = {};
    const tm* time = localtime(&t);
    if (nullptr != time)
        strftime(buffer, sizeof(buffer), "%m/%d/%Y %H:%M:%S", time);
    return std::string(buffer);
}

int main(int argc, char** argv) try
{
    // Parse command line arguments
    CmdLine cmd("librealsense rs-embed tool", ' ', RS_EMBED_VERSION);
    ValueArg<string> inputFilename("i", "input", "Input filename", true, "", "input-file");
    ValueArg<string> outputFilename("o", "output", "Output filename", false, "", "output-file");
    ValueArg<string> objectName("n", "name", "Name", false, "", "object-name");

    cmd.add(inputFilename);
    cmd.add(outputFilename);
    cmd.add(objectName);
    cmd.parse(argc, argv);

    auto input = inputFilename.getValue();
    auto output = outputFilename.getValue();
    auto name = objectName.getValue();

    if (ends_with(input, ".obj"))
    {
        std::vector<float3> vertex_data;
        std::vector<float3> normals_raw_data;
        std::vector<float3> normals_data;
        std::vector<int6> index_raw_data;
        std::vector<short3> index_data;

        if (file_exists(input))
        {
            std::ifstream file(input);
            std::string str;
            while (std::getline(file, str))
            {
                if (str.size())
                {
                    if (str[0] == 'v')
                    {
                        float a, b, c;
                        if (str[1] == 'n')
                        {
                            sscanf(str.c_str(), "vn %f %f %f", &a, &b, &c);
                            normals_raw_data.push_back({ a, b, c });
                        }
                        else
                        {
                            sscanf(str.c_str(), "v %f %f %f", &a, &b, &c);
                            vertex_data.push_back({ a, b, c });
                        }
                    }
                    if (str[0] == 'f')
                    {
                        int x, y, z, a, b, c;
                        sscanf(str.c_str(), "f %d//%d %d//%d %d//%d", &x, &a, &y, &b, &z, &c);
                        index_raw_data.push_back({ x, y, z, a, b, c });
                    }
                }
            }
        }
        else
        {
            std::cout << "file: " << input << " could not be found!" << std::endl;
            return EXIT_FAILURE;
        }

        normals_data.resize(vertex_data.size());
        for (auto& idx : index_raw_data)
        {
            // TODO - normals data are currently disabled
            // normals_data[idx.x] = normals_raw_data[idx.a];
            // normals_data[idx.y] = normals_raw_data[idx.b];
            // normals_data[idx.z] = normals_raw_data[idx.c];
            index_data.push_back({ static_cast<uint16_t>(idx.x - 1),
                                    static_cast<uint16_t>(idx.y - 1),
                                    static_cast<uint16_t>(idx.z - 1) });
        }

        size_t vertex_data_size = vertex_data.size() * sizeof(float3);
        size_t index_data_size = index_data.size() * sizeof(short3);
        //size_t normals_data_size = normals_data.size() * sizeof(float3);

        std::vector<uint8_t> data(vertex_data_size + index_data_size, 0);
        memcpy(data.data(), vertex_data.data(), vertex_data_size);
        memcpy(data.data() + vertex_data_size, index_data.data(), index_data_size);
        //memcpy(data.data() + vertex_data_size + index_data_size, normals_data.data(), normals_data_size);

        // compress szSource into pchCompressed
        auto rawDataSize = (int)data.size();
        auto compressBufSize = LZ4_compressBound(rawDataSize);
        char* pchCompressed = new char[compressBufSize];
        memset(pchCompressed, compressBufSize, 0);
        int nCompressedSize = LZ4_compress_default((const char*)data.data(), pchCompressed, rawDataSize, compressBufSize);

        ofstream myfile;
        myfile.open(output);
        myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n";
        myfile << "// Copyright(c) 2021 Intel Corporation. All Rights Reserved.\n\n";
        myfile << "// This file is auto-generated from " << name << ".obj using rs-embed tool version: " << RS_EMBED_VERSION <<"\n";
        myfile << "// Generation time: " << get_current_time() << ".\n\n";
        myfile << "#pragma once\n";
        myfile << "static uint32_t " << name << "_obj_data [] { ";

        auto nAllignedCompressedSize = nCompressedSize;
        auto leftover = nCompressedSize % 4;
        if (leftover % 4 != 0) nAllignedCompressedSize += (4 - leftover);

        for (int i = 0; i < nAllignedCompressedSize; i += 4)
        {
            uint32_t* ptr = (uint32_t*)(pchCompressed + i);
            myfile << "0x" << std::hex << (int)(*ptr);
            if (i < nAllignedCompressedSize - 1) myfile << ",";
        }

        myfile << "};\n";

        myfile << "#include <lz4.h>\n";
        myfile << "#include <vector>\n";

        myfile << "inline void uncompress_" << name << "_obj(std::vector<float3>& vertex_data, std::vector<float3>& normals, std::vector<short3>& index_data)\n";
        myfile << "{\n";
        myfile << "    std::vector<char> uncompressed(0x" << std::hex << rawDataSize << ", 0);\n";
        myfile << "    LZ4_decompress_safe((const char*)" << name << "_obj_data, uncompressed.data(), 0x" << std::hex << nCompressedSize << ", 0x" << std::hex << rawDataSize << ");\n";
        myfile << "    const int vertex_size = 0x" << std::hex << vertex_data.size() << " * sizeof(float3);\n";
        myfile << "    const int index_size = 0x" << std::hex << index_data.size() << " * sizeof(short3);\n";
        myfile << "    vertex_data.resize(0x" << std::hex << vertex_data.size() << ");\n";
        myfile << "    memcpy(vertex_data.data(), uncompressed.data(), vertex_size);\n";
        myfile << "    index_data.resize(0x" << std::hex << index_data.size() << ");\n";
        myfile << "    memcpy(index_data.data(), uncompressed.data() + vertex_size, index_size);\n";
        myfile << "    //normals.resize(0x" << std::hex << vertex_data.size() << ");\n";
        myfile << "    //memcpy(normals.data(), uncompressed.data() + vertex_size + index_size, vertex_size);\n";
        myfile << "}\n";

        myfile.close();
    }

    if (ends_with(input, ".png"))
    {
        ifstream ifs(input, ios::binary | ios::ate);
        ifstream::pos_type pos = ifs.tellg();

        std::vector<char> buffer(pos);

        ifs.seekg(0, ios::beg);
        ifs.read(&buffer[0], pos);

        ofstream myfile;
        myfile.open(output);
        myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n";
        myfile << "// Copyright(c) 2021 Intel Corporation. All Rights Reserved.\n\n";
        myfile << "// This file is auto-generated from " << name << ".png using rs-embed tool version: " << RS_EMBED_VERSION << "\n";
        myfile << "// Generation time: " << get_current_time() << ".\n\n";

        myfile << "static uint32_t " << name << "_png_size = 0x" << std::hex << buffer.size() << ";\n";

        myfile << "static uint8_t " << name << "_png_data [] { ";
        for (int i = 0; i < buffer.size(); i++)
        {
            uint8_t byte = buffer[i];
            myfile << "0x" << std::hex << (int)byte;
            if (i < buffer.size() - 1) myfile << ",";
        }
        myfile << "};\n";

        myfile.close();
    }

    return EXIT_SUCCESS;
}
catch (const exception& e)
{
    cerr << e.what() << endl;
    return EXIT_FAILURE;
}
catch (...)
{
    cerr << "some error" << endl;
    return EXIT_FAILURE;
}
<commit_msg>update includes brackets<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2021 Intel Corporation. All Rights Reserved.

#include <iostream>
#include <string>
#include <string.h> // memcpy
#include <fstream>
#include <vector>

#include <tclap/CmdLine.h>
#include <lz4.h>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

#define RS_EMBED_VERSION "0.0.0.1"

struct float3
{
    float x, y, z;
};

struct short3
{
    uint16_t x, y, z;
};

using namespace std;
using namespace TCLAP;

bool file_exists(const std::string& name) {
    std::ifstream f(name.c_str());
    return f.good();
}

struct int6
{
    int x, y, z, a, b, c;
};

bool ends_with(const std::string& s, const std::string& suffix)
{
    auto i = s.rbegin(), j = suffix.rbegin();
    for (; i != s.rend() && j != suffix.rend() && *i == *j;
        i++, j++);
    return j == suffix.rend();
}

std::string get_current_time()
{
    auto t = time(nullptr);
    char buffer[20] = {};
    const tm* time = localtime(&t);
    if (nullptr != time)
        strftime(buffer, sizeof(buffer), "%m/%d/%Y %H:%M:%S", time);
    return std::string(buffer);
}

int main(int argc, char** argv) try
{
    // Parse command line arguments
    CmdLine cmd("librealsense rs-embed tool", ' ', RS_EMBED_VERSION);
    ValueArg<string> inputFilename("i", "input", "Input filename", true, "", "input-file");
    ValueArg<string> outputFilename("o", "output", "Output filename", false, "", "output-file");
    ValueArg<string> objectName("n", "name", "Name", false, "", "object-name");

    cmd.add(inputFilename);
    cmd.add(outputFilename);
    cmd.add(objectName);
    cmd.parse(argc, argv);

    auto input = inputFilename.getValue();
    auto output = outputFilename.getValue();
    auto name = objectName.getValue();

    if (ends_with(input, ".obj"))
    {
        std::vector<float3> vertex_data;
        std::vector<float3> normals_raw_data;
        std::vector<float3> normals_data;
        std::vector<int6> index_raw_data;
        std::vector<short3> index_data;

        if (file_exists(input))
        {
            std::ifstream file(input);
            std::string str;
            while (std::getline(file, str))
            {
                if (str.size())
                {
                    if (str[0] == 'v')
                    {
                        float a, b, c;
                        if (str[1] == 'n')
                        {
                            sscanf(str.c_str(), "vn %f %f %f", &a, &b, &c);
                            normals_raw_data.push_back({ a, b, c });
                        }
                        else
                        {
                            sscanf(str.c_str(), "v %f %f %f", &a, &b, &c);
                            vertex_data.push_back({ a, b, c });
                        }
                    }
                    if (str[0] == 'f')
                    {
                        int x, y, z, a, b, c;
                        sscanf(str.c_str(), "f %d//%d %d//%d %d//%d", &x, &a, &y, &b, &z, &c);
                        index_raw_data.push_back({ x, y, z, a, b, c });
                    }
                }
            }
        }
        else
        {
            std::cout << "file: " << input << " could not be found!" << std::endl;
            return EXIT_FAILURE;
        }

        normals_data.resize(vertex_data.size());
        for (auto& idx : index_raw_data)
        {
            // TODO - normals data are currently disabled
            // normals_data[idx.x] = normals_raw_data[idx.a];
            // normals_data[idx.y] = normals_raw_data[idx.b];
            // normals_data[idx.z] = normals_raw_data[idx.c];
            index_data.push_back({ static_cast<uint16_t>(idx.x - 1),
                                    static_cast<uint16_t>(idx.y - 1),
                                    static_cast<uint16_t>(idx.z - 1) });
        }

        size_t vertex_data_size = vertex_data.size() * sizeof(float3);
        size_t index_data_size = index_data.size() * sizeof(short3);
        //size_t normals_data_size = normals_data.size() * sizeof(float3);

        std::vector<uint8_t> data(vertex_data_size + index_data_size, 0);
        memcpy(data.data(), vertex_data.data(), vertex_data_size);
        memcpy(data.data() + vertex_data_size, index_data.data(), index_data_size);
        //memcpy(data.data() + vertex_data_size + index_data_size, normals_data.data(), normals_data_size);

        // compress szSource into pchCompressed
        auto rawDataSize = (int)data.size();
        auto compressBufSize = LZ4_compressBound(rawDataSize);
        char* pchCompressed = new char[compressBufSize];
        memset(pchCompressed, compressBufSize, 0);
        int nCompressedSize = LZ4_compress_default((const char*)data.data(), pchCompressed, rawDataSize, compressBufSize);

        ofstream myfile;
        myfile.open(output);
        myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n";
        myfile << "// Copyright(c) 2021 Intel Corporation. All Rights Reserved.\n\n";
        myfile << "// This file is auto-generated from " << name << ".obj using rs-embed tool version: " << RS_EMBED_VERSION <<"\n";
        myfile << "// Generation time: " << get_current_time() << ".\n\n";
        myfile << "#pragma once\n";
        myfile << "static uint32_t " << name << "_obj_data [] { ";

        auto nAllignedCompressedSize = nCompressedSize;
        auto leftover = nCompressedSize % 4;
        if (leftover % 4 != 0) nAllignedCompressedSize += (4 - leftover);

        for (int i = 0; i < nAllignedCompressedSize; i += 4)
        {
            uint32_t* ptr = (uint32_t*)(pchCompressed + i);
            myfile << "0x" << std::hex << (int)(*ptr);
            if (i < nAllignedCompressedSize - 1) myfile << ",";
        }

        myfile << "};\n";

        myfile << "#include <lz4.h>\n";
        myfile << "#include <vector>\n";

        myfile << "inline void uncompress_" << name << "_obj(std::vector<float3>& vertex_data, std::vector<float3>& normals, std::vector<short3>& index_data)\n";
        myfile << "{\n";
        myfile << "    std::vector<char> uncompressed(0x" << std::hex << rawDataSize << ", 0);\n";
        myfile << "    LZ4_decompress_safe((const char*)" << name << "_obj_data, uncompressed.data(), 0x" << std::hex << nCompressedSize << ", 0x" << std::hex << rawDataSize << ");\n";
        myfile << "    const int vertex_size = 0x" << std::hex << vertex_data.size() << " * sizeof(float3);\n";
        myfile << "    const int index_size = 0x" << std::hex << index_data.size() << " * sizeof(short3);\n";
        myfile << "    vertex_data.resize(0x" << std::hex << vertex_data.size() << ");\n";
        myfile << "    memcpy(vertex_data.data(), uncompressed.data(), vertex_size);\n";
        myfile << "    index_data.resize(0x" << std::hex << index_data.size() << ");\n";
        myfile << "    memcpy(index_data.data(), uncompressed.data() + vertex_size, index_size);\n";
        myfile << "    //normals.resize(0x" << std::hex << vertex_data.size() << ");\n";
        myfile << "    //memcpy(normals.data(), uncompressed.data() + vertex_size + index_size, vertex_size);\n";
        myfile << "}\n";

        myfile.close();
    }

    if (ends_with(input, ".png"))
    {
        ifstream ifs(input, ios::binary | ios::ate);
        ifstream::pos_type pos = ifs.tellg();

        std::vector<char> buffer(pos);

        ifs.seekg(0, ios::beg);
        ifs.read(&buffer[0], pos);

        ofstream myfile;
        myfile.open(output);
        myfile << "// License: Apache 2.0. See LICENSE file in root directory.\n";
        myfile << "// Copyright(c) 2021 Intel Corporation. All Rights Reserved.\n\n";
        myfile << "// This file is auto-generated from " << name << ".png using rs-embed tool version: " << RS_EMBED_VERSION << "\n";
        myfile << "// Generation time: " << get_current_time() << ".\n\n";

        myfile << "static uint32_t " << name << "_png_size = 0x" << std::hex << buffer.size() << ";\n";

        myfile << "static uint8_t " << name << "_png_data [] { ";
        for (int i = 0; i < buffer.size(); i++)
        {
            uint8_t byte = buffer[i];
            myfile << "0x" << std::hex << (int)byte;
            if (i < buffer.size() - 1) myfile << ",";
        }
        myfile << "};\n";

        myfile.close();
    }

    return EXIT_SUCCESS;
}
catch (const exception& e)
{
    cerr << e.what() << endl;
    return EXIT_FAILURE;
}
catch (...)
{
    cerr << "some error" << endl;
    return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>// main.cpp

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <slang.h>

int main(
    int argc,
    char** argv)
{
    // TODO: parse arguments

    assert(argc >= 2);
    char const* inputPath = argv[1];

    // Slurp in the input file, so that we can compile and run it
    FILE* inputFile;
    fopen_s(&inputFile, inputPath, "rb");
    assert(inputFile);

    fseek(inputFile, 0, SEEK_END);
    size_t inputSize = ftell(inputFile);
    fseek(inputFile, 0, SEEK_SET);

    char* inputText = (char*) malloc(inputSize + 1);
    fread(inputText, inputSize, 1, inputFile);
    inputText[inputSize] = 0;
    fclose(inputFile);

    // TODO: scan through the text to find comments,
    // that instruct us how to generate input and
    // consume output when running the test.

    //

    SlangSession* session = spCreateSession(nullptr);
    SlangCompileRequest* request = spCreateCompileRequest(session);

    spSetCompileFlags(
        request,
        SLANG_COMPILE_FLAG_USE_IR);

    spSetOutputContainerFormat(
        request,
        SLANG_CONTAINER_FORMAT_SLANG_MODULE);

    int translationUnitIndex = spAddTranslationUnit(
        request,
        SLANG_SOURCE_LANGUAGE_SLANG,
        nullptr);

    spAddTranslationUnitSourceString(
        request,
        translationUnitIndex,
        inputPath,
        inputText);

    int entryPointIndex = spAddEntryPoint(
        request,
        translationUnitIndex,
        "main",
        spFindProfile(session, "cs_5_0"));

    if( spCompile(request) != 0 )
    {
        char const* output = spGetDiagnosticOutput(request);
        fputs(output, stderr);
        exit(1);
    }

    // Things compiled, so now we need to run them...

    // Extract the bytecode
    size_t bytecodeSize = 0;
    void const* bytecode = spGetCompileRequestCode(request, &bytecodeSize);

    // Now we need to create an execution context to go and run the bytecode we got

    SlangVM* vm = SlangVM_create();

    SlangVMModule* vmModule = SlangVMModule_load(
        vm,
        bytecode,
        bytecodeSize);

    SlangVMFunc* vmFunc = (SlangVMFunc*)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "main");

    int32_t*& inputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "input");

    int32_t*& outputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "output");

    SlangVMThread* vmThread = SlangVMThread_create(
        vm);

    int32_t inputData[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
    int32_t outputData[8] = { 0 };

    inputArg = inputData;
    outputArg = outputData;

    // TODO: set arguments based on specification from the user...
    for (uint32_t threadID = 0; threadID < 8; ++threadID)
    {
#if 0
        fprintf(stderr, "\n\nthreadID = %u\n\n", threadID);
        fflush(stderr);
#endif

        SlangVMThread_beginCall(vmThread, vmFunc);

        SlangVMThread_setArg(
            vmThread,
            0,
            &threadID,
            sizeof(threadID));

        SlangVMThread_resume(vmThread);
    }

    for (uint32_t ii = 0; ii < 8; ++ii)
    {
        fprintf(stdout, "outputData[%u] = %d\n", ii, outputData[ii]);
    }

    spDestroyCompileRequest(request);
    spDestroySession(session);

    return 0;
}
<commit_msg>fix linux build<commit_after>// main.cpp

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../source/core/secure-crt.h"
#include <slang.h>

int main(
    int argc,
    char** argv)
{
    // TODO: parse arguments

    assert(argc >= 2);
    char const* inputPath = argv[1];

    // Slurp in the input file, so that we can compile and run it
    FILE* inputFile;
    fopen_s(&inputFile, inputPath, "rb");
    assert(inputFile);

    fseek(inputFile, 0, SEEK_END);
    size_t inputSize = ftell(inputFile);
    fseek(inputFile, 0, SEEK_SET);

    char* inputText = (char*) malloc(inputSize + 1);
    fread(inputText, inputSize, 1, inputFile);
    inputText[inputSize] = 0;
    fclose(inputFile);

    // TODO: scan through the text to find comments,
    // that instruct us how to generate input and
    // consume output when running the test.

    //

    SlangSession* session = spCreateSession(nullptr);
    SlangCompileRequest* request = spCreateCompileRequest(session);

    spSetCompileFlags(
        request,
        SLANG_COMPILE_FLAG_USE_IR);

    spSetOutputContainerFormat(
        request,
        SLANG_CONTAINER_FORMAT_SLANG_MODULE);

    int translationUnitIndex = spAddTranslationUnit(
        request,
        SLANG_SOURCE_LANGUAGE_SLANG,
        nullptr);

    spAddTranslationUnitSourceString(
        request,
        translationUnitIndex,
        inputPath,
        inputText);

    int entryPointIndex = spAddEntryPoint(
        request,
        translationUnitIndex,
        "main",
        spFindProfile(session, "cs_5_0"));

    if( spCompile(request) != 0 )
    {
        char const* output = spGetDiagnosticOutput(request);
        fputs(output, stderr);
        exit(1);
    }

    // Things compiled, so now we need to run them...

    // Extract the bytecode
    size_t bytecodeSize = 0;
    void const* bytecode = spGetCompileRequestCode(request, &bytecodeSize);

    // Now we need to create an execution context to go and run the bytecode we got

    SlangVM* vm = SlangVM_create();

    SlangVMModule* vmModule = SlangVMModule_load(
        vm,
        bytecode,
        bytecodeSize);

    SlangVMFunc* vmFunc = (SlangVMFunc*)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "main");

    int32_t*& inputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "input");

    int32_t*& outputArg = *(int32_t**)SlangVMModule_findGlobalSymbolPtr(
        vmModule,
        "output");

    SlangVMThread* vmThread = SlangVMThread_create(
        vm);

    int32_t inputData[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
    int32_t outputData[8] = { 0 };

    inputArg = inputData;
    outputArg = outputData;

    // TODO: set arguments based on specification from the user...
    for (uint32_t threadID = 0; threadID < 8; ++threadID)
    {
#if 0
        fprintf(stderr, "\n\nthreadID = %u\n\n", threadID);
        fflush(stderr);
#endif

        SlangVMThread_beginCall(vmThread, vmFunc);

        SlangVMThread_setArg(
            vmThread,
            0,
            &threadID,
            sizeof(threadID));

        SlangVMThread_resume(vmThread);
    }

    for (uint32_t ii = 0; ii < 8; ++ii)
    {
        fprintf(stdout, "outputData[%u] = %d\n", ii, outputData[ii]);
    }

    spDestroyCompileRequest(request);
    spDestroySession(session);

    return 0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>

#include "DexClass.h"
#include "PassRegistry.h"
#include "Timer.h"
#include "ToolsCommon.h"

namespace {

struct Arguments {
  std::string input_ir_dir;
  std::string output_ir_dir;
  std::vector<std::string> pass_names;
  RedexOptions redex_options;
};

Arguments parse_args(int argc, char* argv[]) {
  namespace po = boost::program_options;
  po::options_description desc(
      "Run one pass with dex and IR meta as input and output");
  desc.add_options()("help,h", "produce help message");
  desc.add_options()("input-ir,i", po::value<std::string>(),
                     "input dex and IR meta directory");
  desc.add_options()("output-ir,o",
                     po::value<std::string>(),
                     "output dex and IR meta directory");
  desc.add_options()("pass-name,p", po::value<std::vector<std::string>>(),
                     "pass name");

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help")) {
    desc.print(std::cout);
    exit(EXIT_SUCCESS);
  }

  Arguments args;

  if (vm.count("input-ir")) {
    args.input_ir_dir = vm["input-ir"].as<std::string>();
  }

  if (vm.count("output-ir")) {
    args.output_ir_dir = vm["output-ir"].as<std::string>();
  }
  if (args.output_ir_dir.empty()) {
    std::cerr << "output-dir is empty\n";
    exit(EXIT_FAILURE);
  }
  boost::filesystem::create_directory(args.output_ir_dir);

  if (vm.count("pass-name")) {
    args.pass_names = vm["pass-name"].as<std::vector<std::string>>();
  }

  return args;
}

/**
 * Process entry_data : Load config file and change the passes list
 */
Json::Value process_entry_data(const Json::Value& entry_data,
                               const Arguments& args) {
  Json::Value config_data =
      redex::parse_config(entry_data["config"].asString());
  // Change passes list in config data.
  config_data["redex"]["passes"] = Json::arrayValue;
  Json::Value& passes_list = config_data["redex"]["passes"];
  for (const std::string& pass_name : args.pass_names) {
    passes_list.append(pass_name);
  }
  int len = config_data["redex"]["passes"].size();
  if (len > 0 && passes_list[len - 1].asString() != "RegAllocPass") {
    passes_list.append("RegAllocPass");
  }

  // apk_dir
  if (entry_data.isMember("apk_dir")) {
    config_data["apk_dir"] = entry_data["apk_dir"].asString();
  }

  return config_data;
}
} // namespace

int main(int argc, char* argv[]) {
  Timer opt_timer("Redex-opt");
  Arguments args = parse_args(argc, argv);

  g_redex = new RedexContext();

  Json::Value entry_data;

  DexStoresVector stores;

  redex::load_all_intermediate(args.input_ir_dir, stores, &entry_data);
  args.redex_options.deserialize(entry_data);

  Json::Value config_data = process_entry_data(entry_data, args);
  ConfigFiles cfg(std::move(config_data), args.output_ir_dir);

  const auto& passes = PassRegistry::get().get_passes();
  PassManager manager(passes, config_data, args.redex_options);
  manager.set_testing_mode();
  manager.run_passes(stores, cfg);

  redex::write_all_intermediate(cfg, args.output_ir_dir, args.redex_options,
                                stores, entry_data);

  delete g_redex;
  return 0;
}
<commit_msg>Set input dex magic to first DexStore<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>

#include "DexClass.h"
#include "DexLoader.h"
#include "PassRegistry.h"
#include "Timer.h"
#include "ToolsCommon.h"

namespace {

struct Arguments {
  std::string input_ir_dir;
  std::string output_ir_dir;
  std::vector<std::string> pass_names;
  RedexOptions redex_options;
};

Arguments parse_args(int argc, char* argv[]) {
  namespace po = boost::program_options;
  po::options_description desc(
      "Run one pass with dex and IR meta as input and output");
  desc.add_options()("help,h", "produce help message");
  desc.add_options()("input-ir,i", po::value<std::string>(),
                     "input dex and IR meta directory");
  desc.add_options()("output-ir,o",
                     po::value<std::string>(),
                     "output dex and IR meta directory");
  desc.add_options()("pass-name,p", po::value<std::vector<std::string>>(),
                     "pass name");

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help")) {
    desc.print(std::cout);
    exit(EXIT_SUCCESS);
  }

  Arguments args;

  if (vm.count("input-ir")) {
    args.input_ir_dir = vm["input-ir"].as<std::string>();
  }

  if (vm.count("output-ir")) {
    args.output_ir_dir = vm["output-ir"].as<std::string>();
  }
  if (args.output_ir_dir.empty()) {
    std::cerr << "output-dir is empty\n";
    exit(EXIT_FAILURE);
  }
  boost::filesystem::create_directory(args.output_ir_dir);

  if (vm.count("pass-name")) {
    args.pass_names = vm["pass-name"].as<std::vector<std::string>>();
  }

  return args;
}

/**
 * Process entry_data : Load config file and change the passes list
 */
Json::Value process_entry_data(const Json::Value& entry_data,
                               const Arguments& args) {
  Json::Value config_data =
      redex::parse_config(entry_data["config"].asString());
  // Change passes list in config data.
  config_data["redex"]["passes"] = Json::arrayValue;
  Json::Value& passes_list = config_data["redex"]["passes"];
  for (const std::string& pass_name : args.pass_names) {
    passes_list.append(pass_name);
  }
  int len = config_data["redex"]["passes"].size();
  if (len > 0 && passes_list[len - 1].asString() != "RegAllocPass") {
    passes_list.append("RegAllocPass");
  }

  // apk_dir
  if (entry_data.isMember("apk_dir")) {
    config_data["apk_dir"] = entry_data["apk_dir"].asString();
  }

  return config_data;
}
} // namespace

int main(int argc, char* argv[]) {
  Timer opt_timer("Redex-opt");
  Arguments args = parse_args(argc, argv);

  g_redex = new RedexContext();

  Json::Value entry_data;

  DexStoresVector stores;

  redex::load_all_intermediate(args.input_ir_dir, stores, &entry_data);

  // Set input dex magic to the first DexStore from the first dex file
  if (stores.size() > 0) {
    auto first_dex_path = boost::filesystem::path(args.input_ir_dir) /
                          entry_data["dex_list"][0]["list"][0].asString();
    stores[0].set_dex_magic(load_dex_magic_from_dex(first_dex_path.c_str()));
  }

  args.redex_options.deserialize(entry_data);

  Json::Value config_data = process_entry_data(entry_data, args);
  ConfigFiles cfg(std::move(config_data), args.output_ir_dir);

  const auto& passes = PassRegistry::get().get_passes();
  PassManager manager(passes, config_data, args.redex_options);
  manager.set_testing_mode();
  manager.run_passes(stores, cfg);

  redex::write_all_intermediate(cfg, args.output_ir_dir, args.redex_options,
                                stores, entry_data);

  delete g_redex;
  return 0;
}
<|endoftext|>


<commit_before>//===--- SILOpt.cpp - SIL Optimization Driver -----------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is a tool for reading sil files and running sil passes on them. The
// targeted usecase is debugging and testing SIL passes.
//
//===----------------------------------------------------------------------===//

#include "swift/Strings.h"
#include "swift/Subsystems.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/SILOptions.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Frontend/DiagnosticVerifier.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/SerializedSILLoader.h"
#include "swift/Serialization/SerializationOptions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
using namespace swift;

namespace {

enum class OptGroup {
  Unknown, Diagnostics, Performance
};

} // end anonymous namespace

static llvm::cl::opt<std::string>
InputFilename(llvm::cl::desc("input file"), llvm::cl::init("-"),
              llvm::cl::Positional);

static llvm::cl::opt<std::string>
OutputFilename("o", llvm::cl::desc("output filename"));

static llvm::cl::list<std::string>
ImportPaths("I", llvm::cl::desc("add a directory to the import search path"));

static llvm::cl::list<std::string>
FrameworkPaths("F", llvm::cl::desc("add a directory to the framework search path"));

static llvm::cl::opt<std::string>
ModuleName("module-name", llvm::cl::desc("The name of the module if processing"
                                         " a module. Necessary for processing "
                                         "stdin."));

static llvm::cl::opt<bool>
EnableResilience("enable-resilience",
                 llvm::cl::desc("Compile the module to export resilient "
                                "interfaces for all public declarations by "
                                "default"));

static llvm::cl::opt<std::string>
ResourceDir("resource-dir",
    llvm::cl::desc("The directory that holds the compiler resource files"));

static llvm::cl::opt<std::string>
SDKPath("sdk", llvm::cl::desc("The path to the SDK for use with the clang "
                              "importer."),
        llvm::cl::init(""));

static llvm::cl::opt<std::string>
Target("target", llvm::cl::desc("target triple"));

static llvm::cl::opt<OptGroup> OptimizationGroup(
    llvm::cl::desc("Predefined optimization groups:"),
    llvm::cl::values(clEnumValN(OptGroup::Diagnostics, "diagnostics",
                                "Run diagnostic passes"),
                     clEnumValN(OptGroup::Performance, "O",
                                "Run performance passes"),
                     clEnumValEnd),
    llvm::cl::init(OptGroup::Unknown));

static llvm::cl::list<PassKind>
Passes(llvm::cl::desc("Passes:"),
       llvm::cl::values(
#define PASS(ID, NAME, DESCRIPTION) clEnumValN(PassKind::ID, NAME, DESCRIPTION),
#include "swift/SILOptimizer/PassManager/Passes.def"
			clEnumValEnd));

static llvm::cl::opt<bool>
PrintStats("print-stats", llvm::cl::desc("Print various statistics"));

static llvm::cl::opt<bool>
VerifyMode("verify",
           llvm::cl::desc("verify diagnostics against expected-"
                          "{error|warning|note} annotations"));

static llvm::cl::opt<unsigned>
AssertConfId("assert-conf-id", llvm::cl::Hidden,
             llvm::cl::init(0));

static llvm::cl::opt<int>
SILInlineThreshold("sil-inline-threshold", llvm::cl::Hidden,
                   llvm::cl::init(-1));

static llvm::cl::opt<bool>
EnableSILVerifyAll("enable-sil-verify-all",
                   llvm::cl::Hidden,
                   llvm::cl::init(true),
                   llvm::cl::desc("Run sil verifications after every pass."));

static llvm::cl::opt<bool>
RemoveRuntimeAsserts("remove-runtime-asserts",
                     llvm::cl::Hidden,
                     llvm::cl::init(false),
                     llvm::cl::desc("Remove runtime assertions (cond_fail)."));

static llvm::cl::opt<bool>
EmitVerboseSIL("emit-verbose-sil",
               llvm::cl::desc("Emit locations during sil emission."));

static llvm::cl::opt<bool>
EmitSIB("emit-sib", llvm::cl::desc("Emit serialized AST + SIL file(s)"));

static llvm::cl::opt<std::string>
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));

static llvm::cl::opt<bool>
EnableSILSortOutput("sil-sort-output", llvm::cl::Hidden,
                    llvm::cl::init(false),
                    llvm::cl::desc("Sort Functions, VTables, Globals, "
                                   "WitnessTables by name to ease diffing."));

static llvm::cl::opt<bool>
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
               llvm::cl::init(false),
               llvm::cl::desc("Do not dump AST."));

static llvm::cl::opt<unsigned>
ASTVerifierProcessCount("ast-verifier-process-count", llvm::cl::Hidden,
                        llvm::cl::init(1));

static llvm::cl::opt<unsigned>
ASTVerifierProcessId("ast-verifier-process-id", llvm::cl::Hidden,
                     llvm::cl::init(1));

static llvm::cl::opt<bool>
PerformWMO("wmo", llvm::cl::desc("Enable whole-module optimizations"));

static void runCommandLineSelectedPasses(SILModule *Module) {
  SILPassManager PM(Module);

  for (auto Pass : Passes) {
    PM.addPass(Pass);
  }
  PM.run();
}

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// getMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement getMainExecutable
// without being given the address of a function in the main executable).
void anchorForGetMainExecutable() {}

int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(argv[0],
          reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  // Give the context the list of search paths to use for modules.
  Invocation.setImportSearchPaths(ImportPaths);
  Invocation.setFrameworkSearchPaths(FrameworkPaths);
  // Set the SDK path and target if given.
  if (SDKPath.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDKPath = SDKROOT;
  }
  if (!SDKPath.empty())
    Invocation.setSDKPath(SDKPath);
  if (!Target.empty())
    Invocation.setTargetTriple(Target);
  if (!ResourceDir.empty())
    Invocation.setRuntimeResourcePath(ResourceDir);
  Invocation.getFrontendOptions().EnableResilience = EnableResilience;
  // Set the module cache path. If not passed in we use the default swift module
  // cache.
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setParseStdlib();
  Invocation.getLangOptions().EnableAccessControl = false;
  Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;

  Invocation.getLangOptions().ASTVerifierProcessCount =
      ASTVerifierProcessCount;
  Invocation.getLangOptions().ASTVerifierProcessId =
      ASTVerifierProcessId;

  // Setup the SIL Options.
  SILOptions &SILOpts = Invocation.getSILOptions();
  SILOpts.InlineThreshold = SILInlineThreshold;
  SILOpts.VerifyAll = EnableSILVerifyAll;
  SILOpts.RemoveRuntimeAsserts = RemoveRuntimeAsserts;
  SILOpts.AssertConfig = AssertConfId;
  if (OptimizationGroup != OptGroup::Diagnostics)
    SILOpts.Optimization = SILOptions::SILOptMode::Optimize;

  // Load the input file.
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
    llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (!FileBufOrErr) {
    fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str());
    exit(-1);
  }

  // If it looks like we have an AST, set the source file kind to SIL and the
  // name of the module to the file's name.
  Invocation.addInputBuffer(FileBufOrErr.get().get());

  serialization::ExtendedValidationInfo extendedInfo;
  auto result = serialization::validateSerializedAST(
      FileBufOrErr.get()->getBuffer(), &extendedInfo);
  bool HasSerializedAST = result.status == serialization::Status::Valid;

  if (HasSerializedAST) {
    const StringRef Stem = ModuleName.size() ?
                             StringRef(ModuleName) :
                             llvm::sys::path::stem(InputFilename);
    Invocation.setModuleName(Stem);
    Invocation.setInputKind(InputFileKind::IFK_Swift_Library);
  } else {
    const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main";
    Invocation.setModuleName(Name);
    Invocation.setInputKind(InputFileKind::IFK_SIL);
  }

  CompilerInstance CI;
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);

  if (!PerformWMO) {
    auto &FrontendOpts = Invocation.getFrontendOptions();
    if (!InputFilename.empty() && InputFilename != "-") {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputFilenames.size());
    } else {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer);
    }
  }

  if (CI.setup(Invocation))
    return 1;

  CI.performSema();

  // If parsing produced an error, don't run any passes.
  if (CI.getASTContext().hadError())
    return 1;

  // Load the SIL if we have a module. We have to do this after SILParse
  // creating the unfortunate double if statement.
  if (HasSerializedAST) {
    assert(!CI.hasSILModule() &&
           "performSema() should not create a SILModule.");
    CI.setSILModule(SILModule::createEmptyModule(CI.getMainModule(),
                                                 CI.getSILOptions()));
    std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create(
        CI.getASTContext(), CI.getSILModule(), nullptr);

    if (extendedInfo.isSIB())
      SL->getAllForModule(CI.getMainModule()->getName(), nullptr);
    else
      SL->getAll();
  }

  // Run the SIL verifier after parsing, so that we verify the module
  // even if no optimization passes are being run.
  CI.getSILModule()->verify();

  // If we're in verify mode, install a custom diagnostic handling for
  // SourceMgr.
  if (VerifyMode)
    enableDiagnosticVerifier(CI.getSourceMgr());

  if (OptimizationGroup == OptGroup::Diagnostics) {
    runSILDiagnosticPasses(*CI.getSILModule());
  } else if (OptimizationGroup == OptGroup::Performance) {
    runSILOptimizationPasses(*CI.getSILModule());
  } else {
    runCommandLineSelectedPasses(CI.getSILModule());
  }

  if (EmitSIB) {
    llvm::SmallString<128> OutputFile;
    if (OutputFilename.size()) {
      OutputFile = OutputFilename;
    } else if (ModuleName.size()) {
      OutputFile = ModuleName;
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    } else {
      OutputFile = CI.getMainModule()->getName().str();
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    }

    SerializationOptions serializationOpts;
    serializationOpts.OutputPath = OutputFile.c_str();
    serializationOpts.SerializeAllSIL = true;
    serializationOpts.IsSIB = true;

    serialize(CI.getMainModule(), serializationOpts, CI.getSILModule());
  } else {
    const StringRef OutputFile = OutputFilename.size() ?
                                   StringRef(OutputFilename) : "-";

    if (OutputFile == "-") {
      CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    } else {
      std::error_code EC;
      llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
      if (EC) {
        llvm::errs() << "while opening '" << OutputFile << "': "
                     << EC.message() << '\n';
        return 1;
      }
      CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    }
  }

  bool HadError = CI.getASTContext().hadError();

  // If we're in -verify mode, we've buffered up all of the generated
  // diagnostics.  Check now to ensure that they meet our expectations.
  if (VerifyMode) {
    HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs());
    DiagnosticEngine &diags = CI.getDiags();
    if (diags.hasFatalErrorOccurred() &&
        !Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {
      diags.resetHadAnyError();
      diags.diagnose(SourceLoc(), diag::verify_encountered_fatal);
      HadError = true;
    }
  }

  return HadError;
}
<commit_msg>Revert "sil-opt: Run SIL verifier after parsing"<commit_after>//===--- SILOpt.cpp - SIL Optimization Driver -----------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is a tool for reading sil files and running sil passes on them. The
// targeted usecase is debugging and testing SIL passes.
//
//===----------------------------------------------------------------------===//

#include "swift/Strings.h"
#include "swift/Subsystems.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/SILOptions.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Frontend/DiagnosticVerifier.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/SerializedSILLoader.h"
#include "swift/Serialization/SerializationOptions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
using namespace swift;

namespace {

enum class OptGroup {
  Unknown, Diagnostics, Performance
};

} // end anonymous namespace

static llvm::cl::opt<std::string>
InputFilename(llvm::cl::desc("input file"), llvm::cl::init("-"),
              llvm::cl::Positional);

static llvm::cl::opt<std::string>
OutputFilename("o", llvm::cl::desc("output filename"));

static llvm::cl::list<std::string>
ImportPaths("I", llvm::cl::desc("add a directory to the import search path"));

static llvm::cl::list<std::string>
FrameworkPaths("F", llvm::cl::desc("add a directory to the framework search path"));

static llvm::cl::opt<std::string>
ModuleName("module-name", llvm::cl::desc("The name of the module if processing"
                                         " a module. Necessary for processing "
                                         "stdin."));

static llvm::cl::opt<bool>
EnableResilience("enable-resilience",
                 llvm::cl::desc("Compile the module to export resilient "
                                "interfaces for all public declarations by "
                                "default"));

static llvm::cl::opt<std::string>
ResourceDir("resource-dir",
    llvm::cl::desc("The directory that holds the compiler resource files"));

static llvm::cl::opt<std::string>
SDKPath("sdk", llvm::cl::desc("The path to the SDK for use with the clang "
                              "importer."),
        llvm::cl::init(""));

static llvm::cl::opt<std::string>
Target("target", llvm::cl::desc("target triple"));

static llvm::cl::opt<OptGroup> OptimizationGroup(
    llvm::cl::desc("Predefined optimization groups:"),
    llvm::cl::values(clEnumValN(OptGroup::Diagnostics, "diagnostics",
                                "Run diagnostic passes"),
                     clEnumValN(OptGroup::Performance, "O",
                                "Run performance passes"),
                     clEnumValEnd),
    llvm::cl::init(OptGroup::Unknown));

static llvm::cl::list<PassKind>
Passes(llvm::cl::desc("Passes:"),
       llvm::cl::values(
#define PASS(ID, NAME, DESCRIPTION) clEnumValN(PassKind::ID, NAME, DESCRIPTION),
#include "swift/SILOptimizer/PassManager/Passes.def"
			clEnumValEnd));

static llvm::cl::opt<bool>
PrintStats("print-stats", llvm::cl::desc("Print various statistics"));

static llvm::cl::opt<bool>
VerifyMode("verify",
           llvm::cl::desc("verify diagnostics against expected-"
                          "{error|warning|note} annotations"));

static llvm::cl::opt<unsigned>
AssertConfId("assert-conf-id", llvm::cl::Hidden,
             llvm::cl::init(0));

static llvm::cl::opt<int>
SILInlineThreshold("sil-inline-threshold", llvm::cl::Hidden,
                   llvm::cl::init(-1));

static llvm::cl::opt<bool>
EnableSILVerifyAll("enable-sil-verify-all",
                   llvm::cl::Hidden,
                   llvm::cl::init(true),
                   llvm::cl::desc("Run sil verifications after every pass."));

static llvm::cl::opt<bool>
RemoveRuntimeAsserts("remove-runtime-asserts",
                     llvm::cl::Hidden,
                     llvm::cl::init(false),
                     llvm::cl::desc("Remove runtime assertions (cond_fail)."));

static llvm::cl::opt<bool>
EmitVerboseSIL("emit-verbose-sil",
               llvm::cl::desc("Emit locations during sil emission."));

static llvm::cl::opt<bool>
EmitSIB("emit-sib", llvm::cl::desc("Emit serialized AST + SIL file(s)"));

static llvm::cl::opt<std::string>
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));

static llvm::cl::opt<bool>
EnableSILSortOutput("sil-sort-output", llvm::cl::Hidden,
                    llvm::cl::init(false),
                    llvm::cl::desc("Sort Functions, VTables, Globals, "
                                   "WitnessTables by name to ease diffing."));

static llvm::cl::opt<bool>
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
               llvm::cl::init(false),
               llvm::cl::desc("Do not dump AST."));

static llvm::cl::opt<unsigned>
ASTVerifierProcessCount("ast-verifier-process-count", llvm::cl::Hidden,
                        llvm::cl::init(1));

static llvm::cl::opt<unsigned>
ASTVerifierProcessId("ast-verifier-process-id", llvm::cl::Hidden,
                     llvm::cl::init(1));

static llvm::cl::opt<bool>
PerformWMO("wmo", llvm::cl::desc("Enable whole-module optimizations"));

static void runCommandLineSelectedPasses(SILModule *Module) {
  SILPassManager PM(Module);

  for (auto Pass : Passes) {
    PM.addPass(Pass);
  }
  PM.run();
}

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// getMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement getMainExecutable
// without being given the address of a function in the main executable).
void anchorForGetMainExecutable() {}

int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(argv[0],
          reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  // Give the context the list of search paths to use for modules.
  Invocation.setImportSearchPaths(ImportPaths);
  Invocation.setFrameworkSearchPaths(FrameworkPaths);
  // Set the SDK path and target if given.
  if (SDKPath.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDKPath = SDKROOT;
  }
  if (!SDKPath.empty())
    Invocation.setSDKPath(SDKPath);
  if (!Target.empty())
    Invocation.setTargetTriple(Target);
  if (!ResourceDir.empty())
    Invocation.setRuntimeResourcePath(ResourceDir);
  Invocation.getFrontendOptions().EnableResilience = EnableResilience;
  // Set the module cache path. If not passed in we use the default swift module
  // cache.
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setParseStdlib();
  Invocation.getLangOptions().EnableAccessControl = false;
  Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;

  Invocation.getLangOptions().ASTVerifierProcessCount =
      ASTVerifierProcessCount;
  Invocation.getLangOptions().ASTVerifierProcessId =
      ASTVerifierProcessId;

  // Setup the SIL Options.
  SILOptions &SILOpts = Invocation.getSILOptions();
  SILOpts.InlineThreshold = SILInlineThreshold;
  SILOpts.VerifyAll = EnableSILVerifyAll;
  SILOpts.RemoveRuntimeAsserts = RemoveRuntimeAsserts;
  SILOpts.AssertConfig = AssertConfId;
  if (OptimizationGroup != OptGroup::Diagnostics)
    SILOpts.Optimization = SILOptions::SILOptMode::Optimize;

  // Load the input file.
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
    llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (!FileBufOrErr) {
    fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str());
    exit(-1);
  }

  // If it looks like we have an AST, set the source file kind to SIL and the
  // name of the module to the file's name.
  Invocation.addInputBuffer(FileBufOrErr.get().get());

  serialization::ExtendedValidationInfo extendedInfo;
  auto result = serialization::validateSerializedAST(
      FileBufOrErr.get()->getBuffer(), &extendedInfo);
  bool HasSerializedAST = result.status == serialization::Status::Valid;

  if (HasSerializedAST) {
    const StringRef Stem = ModuleName.size() ?
                             StringRef(ModuleName) :
                             llvm::sys::path::stem(InputFilename);
    Invocation.setModuleName(Stem);
    Invocation.setInputKind(InputFileKind::IFK_Swift_Library);
  } else {
    const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main";
    Invocation.setModuleName(Name);
    Invocation.setInputKind(InputFileKind::IFK_SIL);
  }

  CompilerInstance CI;
  PrintingDiagnosticConsumer PrintDiags;
  CI.addDiagnosticConsumer(&PrintDiags);

  if (!PerformWMO) {
    auto &FrontendOpts = Invocation.getFrontendOptions();
    if (!InputFilename.empty() && InputFilename != "-") {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputFilenames.size());
    } else {
      FrontendOpts.PrimaryInput = SelectedInput(
          FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer);
    }
  }

  if (CI.setup(Invocation))
    return 1;

  CI.performSema();

  // If parsing produced an error, don't run any passes.
  if (CI.getASTContext().hadError())
    return 1;

  // Load the SIL if we have a module. We have to do this after SILParse
  // creating the unfortunate double if statement.
  if (HasSerializedAST) {
    assert(!CI.hasSILModule() &&
           "performSema() should not create a SILModule.");
    CI.setSILModule(SILModule::createEmptyModule(CI.getMainModule(),
                                                 CI.getSILOptions()));
    std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create(
        CI.getASTContext(), CI.getSILModule(), nullptr);

    if (extendedInfo.isSIB())
      SL->getAllForModule(CI.getMainModule()->getName(), nullptr);
    else
      SL->getAll();
  }

  // If we're in verify mode, install a custom diagnostic handling for
  // SourceMgr.
  if (VerifyMode)
    enableDiagnosticVerifier(CI.getSourceMgr());

  if (OptimizationGroup == OptGroup::Diagnostics) {
    runSILDiagnosticPasses(*CI.getSILModule());
  } else if (OptimizationGroup == OptGroup::Performance) {
    runSILOptimizationPasses(*CI.getSILModule());
  } else {
    runCommandLineSelectedPasses(CI.getSILModule());
  }

  if (EmitSIB) {
    llvm::SmallString<128> OutputFile;
    if (OutputFilename.size()) {
      OutputFile = OutputFilename;
    } else if (ModuleName.size()) {
      OutputFile = ModuleName;
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    } else {
      OutputFile = CI.getMainModule()->getName().str();
      llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION);
    }

    SerializationOptions serializationOpts;
    serializationOpts.OutputPath = OutputFile.c_str();
    serializationOpts.SerializeAllSIL = true;
    serializationOpts.IsSIB = true;

    serialize(CI.getMainModule(), serializationOpts, CI.getSILModule());
  } else {
    const StringRef OutputFile = OutputFilename.size() ?
                                   StringRef(OutputFilename) : "-";

    if (OutputFile == "-") {
      CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    } else {
      std::error_code EC;
      llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
      if (EC) {
        llvm::errs() << "while opening '" << OutputFile << "': "
                     << EC.message() << '\n';
        return 1;
      }
      CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
                               EnableSILSortOutput, !DisableASTDump);
    }
  }

  bool HadError = CI.getASTContext().hadError();

  // If we're in -verify mode, we've buffered up all of the generated
  // diagnostics.  Check now to ensure that they meet our expectations.
  if (VerifyMode) {
    HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs());
    DiagnosticEngine &diags = CI.getDiags();
    if (diags.hasFatalErrorOccurred() &&
        !Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {
      diags.resetHadAnyError();
      diags.diagnose(SourceLoc(), diag::verify_encountered_fatal);
      HadError = true;
    }
  }

  return HadError;
}
<|endoftext|>