<commit_before>//==============================================================================
// Single cell simulation view simulation worker
//==============================================================================

#include "cellmlfileruntime.h"
#include "coredaesolver.h"
#include "corenlasolver.h"
#include "coreodesolver.h"
#include "singlecellsimulationviewsimulation.h"
#include "singlecellsimulationviewsimulationworker.h"
#include "thread.h"

//==============================================================================

#include <QTime>

//==============================================================================

namespace OpenCOR {
namespace SingleCellSimulationView {

//==============================================================================

SingleCellSimulationViewSimulationWorker::SingleCellSimulationViewSimulationWorker(const SolverInterfaces &pSolverInterfaces,
                                                                                CellMLSupport::CellmlFileRuntime *pCellmlFileRuntime,
                                                                                SingleCellSimulationViewSimulationData *pData) :
    mStatus(Idling),
    mSolverInterfaces(pSolverInterfaces),
    mCellmlFileRuntime(pCellmlFileRuntime),
    mData(pData),
    mError(false)
{
    // Initialise our progress and let people know about it

    updateAndEmitProgress(0.0);
}

//==============================================================================

SingleCellSimulationViewSimulationWorker::Status SingleCellSimulationViewSimulationWorker::status() const
{
    // Return our status

    return mStatus;
}

//==============================================================================

double SingleCellSimulationViewSimulationWorker::progress() const
{
    // Return our progress

    return mProgress;
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::updateAndEmitProgress(const double &pProgress)
{
    // Set our progress

    mProgress = pProgress;

    // Let people know about our progress

    emit progress(pProgress);
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::run()
{
    // Run ourselves, but only if we are currently idling

    if (mStatus == Idling) {
        // We are running

        mStatus = Running;

        // Let people know that we are running

        emit running();

        // Set up our ODE/DAE solver

        CoreSolver::CoreVoiSolver *voiSolver = 0;
        CoreSolver::CoreOdeSolver *odeSolver = 0;
        CoreSolver::CoreDaeSolver *daeSolver = 0;

        if (mCellmlFileRuntime->needOdeSolver()) {
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare(mData->odeSolverName())) {
                    // The requested ODE solver was found, so retrieve an
                    // instance of it

                    voiSolver = odeSolver = reinterpret_cast<CoreSolver::CoreOdeSolver *>(solverInterface->instance());

                    break;
                }
        } else {
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare("IDA")) {
                    // The requested DAE solver was found, so retrieve an
                    // instance of it

                    voiSolver = daeSolver = reinterpret_cast<CoreSolver::CoreDaeSolver *>(solverInterface->instance());

                    break;
                }
        }

        // Set up our NLA solver, if needed

        if (mCellmlFileRuntime->needNlaSolver())
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare(mData->nlaSolverName())) {
                    // The requested NLA solver was found, so retrieve an
                    // instance of it

                    CoreSolver::setGlobalNlaSolver(reinterpret_cast<CoreSolver::CoreNlaSolver *>(solverInterface->instance()));

                    break;
                }

        // Keep track of any error that might be reported by any of our solvers

        mError = false;

        if (mCellmlFileRuntime->needOdeSolver())
            connect(odeSolver, SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));
        else
            connect(daeSolver, SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));

        if (mCellmlFileRuntime->needNlaSolver())
            connect(CoreSolver::globalNlaSolver(), SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));

        // Retrieve our simulation properties

        double startingPoint = mData->startingPoint();
        double endingPoint   = mData->endingPoint();
        double pointInterval = mData->pointInterval();

        bool increasingPoints = endingPoint > startingPoint;
        const double oneOverPointRange = 1.0/(endingPoint-startingPoint);
        int voiCounter = 0;
        double currentPoint = startingPoint;

        // Initialise our ODE/DAE solver

        if (mCellmlFileRuntime->needOdeSolver()) {
            odeSolver->setProperties(mData->odeSolverProperties());

            odeSolver->initialize(currentPoint,
                                  mCellmlFileRuntime->statesCount(),
                                  mData->constants(), mData->rates(),
                                  mData->states(), mData->algebraic(),
                                  mCellmlFileRuntime->computeRates());
        } else {
            daeSolver->setProperties(mData->daeSolverProperties());

            daeSolver->initialize(currentPoint, endingPoint,
                                  mCellmlFileRuntime->statesCount(),
                                  mCellmlFileRuntime->condVarCount(),
                                  mData->constants(), mData->states(),
                                  mData->rates(), mData->algebraic(),
                                  mData->condVar(),
                                  mCellmlFileRuntime->computeEssentialVariables(),
                                  mCellmlFileRuntime->computeResiduals(),
                                  mCellmlFileRuntime->computeRootInformation(),
                                  mCellmlFileRuntime->computeStateInformation());
        }

        // Initialise our NLA solver
//---GRY--- CHECK do_nonlinearsolve() IN compilermath.cpp SINCE IT ISN'T
//          CURRENTLY NEEDED. HOWEVER, OUR CURRENT APPROACH IS NOT NICE AND WE
//          REALLY SHOULD INITIALISE THINGS HERE...

        if (mCellmlFileRuntime->needNlaSolver()) {
            CoreSolver::globalNlaSolver()->setProperties(mData->nlaSolverProperties());

//            CoreSolver::globalNlaSolver()->initialize(...);
        }

        // Now, we are ready to compute our model, but only if no error has
        // occurred so far

        if (!mError) {
            // Start our timer

            QTime timer;
            int totalElapsedTime = 0;

            timer.start();

            // Our main work loop
QString states;
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ",STATES["+QString::number(i)+"]";
    else
        states = "STATES["+QString::number(i)+"]";
qDebug("time,%s", qPrintable(states));

            while (   (currentPoint != endingPoint) && !mError
                   && (mStatus != Stopped)) {
                // Handle our current point after making sure that all the
                // variables have been computed

                mCellmlFileRuntime->computeVariables()(currentPoint,
                                                       mData->constants(),
                                                       mData->rates(),
                                                       mData->states(),
                                                       mData->algebraic());

//---GRY--- TO BE DONE...
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ","+QString::number(mData->states()[i]);
    else
        states = QString::number(mData->states()[i]);
qDebug("%f,%s", currentPoint, qPrintable(states));

                // Let people know about our progress

                updateAndEmitProgress((currentPoint-startingPoint)*oneOverPointRange);

                // Check whether we should be pausing

                if(mStatus == Pausing) {
                    // We have been asked to pause, so do just that after stopping
                    // our timer

                    totalElapsedTime += timer.elapsed();

                    mStatusMutex.lock();
                        mStatusCondition.wait(&mStatusMutex);
                    mStatusMutex.unlock();

                    // We are running again

                    mStatus = Running;

                    // Let people know that we are running again

                    emit running();

                    // Restart our timer

                    timer.restart();
                }

                // Determine our next point and compute our model up to it

                ++voiCounter;

                voiSolver->solve(currentPoint,
                                 increasingPoints?
                                     qMin(endingPoint, startingPoint+voiCounter*pointInterval):
                                     qMax(endingPoint, startingPoint+voiCounter*pointInterval));

                // Delay things a bit, if (really) needed

                if (mData->delay() && (mStatus != Stopped)) {
                    totalElapsedTime += timer.elapsed();

                    static_cast<Core::Thread *>(thread())->msleep(mData->delay());

                    timer.restart();
                }
            }

            if (!mError && (mStatus != Stopped)) {
                // Handle our last point

//---GRY--- TO BE DONE...
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ","+QString::number(mData->states()[i]);
    else
        states = QString::number(mData->states()[i]);
qDebug("%f,%s", currentPoint, qPrintable(states));

                // Let people know about our final progress, but only if we didn't stop
                // the simulation

                updateAndEmitProgress(1.0);
            }

            // Reset our progress
            // Note: we would normally use updateAndEmitProgress(), but we don't
            //       want to emit the progress, so...

            mProgress = 0.0;

            // Retrieve the total elapsed time

            if (!mError)
                totalElapsedTime += timer.elapsed();

            // We are done, so...

            mStatus = Finished;

            // Let people know that we are done and give them the total elapsed time too

            emit finished(mError?-1:totalElapsedTime);
            // Note: we use -1 as a way to indicate that something went wrong...
        } else {
            // An error occurred, so...

            mStatus = Finished;

            // Let people know that we are done
            // Note: we use -1 as a way to indicate that something went wrong...

            emit finished(-1);
        }

        // Delete our solver(s)

        delete odeSolver;
        delete daeSolver;

        CoreSolver::resetGlobalNlaSolver();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::pause()
{
    // Pause ourselves, but only if we are currently running

    if (mStatus == Running) {
        // We are pausing

        mStatus = Pausing;

        // Let people know that we are pausing

        emit pausing();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::resume()
{
    // Resume ourselves, but only if are currently pausing

    if (mStatus == Pausing) {
        // Actually resume ourselves

        mStatusCondition.wakeAll();

        // We are running again

        mStatus = Running;

        // Let people know that we are running again

        emit running();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::stop()
{
    // Check that we are either running or pausing

    if ((mStatus == Running) || (mStatus == Pausing)) {
        // Resume ourselves, if needed

        if (mStatus == Pausing)
            mStatusCondition.wakeAll();

        // Stop ourselves

        mStatus = Stopped;
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::emitError(const QString &pMessage)
{
    // A solver error occurred, so keep track of it and let people know about it

    mError = true;

    emit error(pMessage);
}

//==============================================================================

}   // namespace SingleCellSimulationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some work on our SingleCellSimulationView plugin (#112).<commit_after>//==============================================================================
// Single cell simulation view simulation worker
//==============================================================================

#include "cellmlfileruntime.h"
#include "coredaesolver.h"
#include "corenlasolver.h"
#include "coreodesolver.h"
#include "singlecellsimulationviewsimulation.h"
#include "singlecellsimulationviewsimulationworker.h"
#include "thread.h"

//==============================================================================

#include <QTime>

//==============================================================================

namespace OpenCOR {
namespace SingleCellSimulationView {

//==============================================================================

SingleCellSimulationViewSimulationWorker::SingleCellSimulationViewSimulationWorker(const SolverInterfaces &pSolverInterfaces,
                                                                                CellMLSupport::CellmlFileRuntime *pCellmlFileRuntime,
                                                                                SingleCellSimulationViewSimulationData *pData) :
    mStatus(Idling),
    mSolverInterfaces(pSolverInterfaces),
    mCellmlFileRuntime(pCellmlFileRuntime),
    mData(pData),
    mError(false)
{
    // Initialise our progress and let people know about it

    updateAndEmitProgress(0.0);
}

//==============================================================================

SingleCellSimulationViewSimulationWorker::Status SingleCellSimulationViewSimulationWorker::status() const
{
    // Return our status

    return mStatus;
}

//==============================================================================

double SingleCellSimulationViewSimulationWorker::progress() const
{
    // Return our progress

    return mProgress;
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::updateAndEmitProgress(const double &pProgress)
{
    // Set our progress

    mProgress = pProgress;

    // Let people know about our progress

    emit progress(pProgress);
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::run()
{
    // Run ourselves, but only if we are currently idling

    if (mStatus == Idling) {
        // We are running

        mStatus = Running;

        // Let people know that we are running

        emit running();

        // Set up our ODE/DAE solver

        CoreSolver::CoreVoiSolver *voiSolver = 0;
        CoreSolver::CoreOdeSolver *odeSolver = 0;
        CoreSolver::CoreDaeSolver *daeSolver = 0;

        if (mCellmlFileRuntime->needOdeSolver()) {
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare(mData->odeSolverName())) {
                    // The requested ODE solver was found, so retrieve an
                    // instance of it

                    voiSolver = odeSolver = reinterpret_cast<CoreSolver::CoreOdeSolver *>(solverInterface->instance());

                    break;
                }
        } else {
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare("IDA")) {
                    // The requested DAE solver was found, so retrieve an
                    // instance of it

                    voiSolver = daeSolver = reinterpret_cast<CoreSolver::CoreDaeSolver *>(solverInterface->instance());

                    break;
                }
        }

        // Set up our NLA solver, if needed

        if (mCellmlFileRuntime->needNlaSolver())
            foreach (SolverInterface *solverInterface, mSolverInterfaces)
                if (!solverInterface->name().compare(mData->nlaSolverName())) {
                    // The requested NLA solver was found, so retrieve an
                    // instance of it

                    CoreSolver::setGlobalNlaSolver(reinterpret_cast<CoreSolver::CoreNlaSolver *>(solverInterface->instance()));

                    break;
                }

        // Keep track of any error that might be reported by any of our solvers

        mError = false;

        if (mCellmlFileRuntime->needOdeSolver())
            connect(odeSolver, SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));
        else
            connect(daeSolver, SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));

        if (mCellmlFileRuntime->needNlaSolver())
            connect(CoreSolver::globalNlaSolver(), SIGNAL(error(const QString &)),
                    this, SLOT(emitError(const QString &)));

        // Retrieve our simulation properties

        double startingPoint = mData->startingPoint();
        double endingPoint   = mData->endingPoint();
        double pointInterval = mData->pointInterval();

        bool increasingPoints = endingPoint > startingPoint;
        const double oneOverPointRange = 1.0/(endingPoint-startingPoint);
        int voiCounter = 0;
        double currentPoint = startingPoint;

        // Initialise our ODE/DAE solver

        if (mCellmlFileRuntime->needOdeSolver()) {
            odeSolver->setProperties(mData->odeSolverProperties());

            odeSolver->initialize(currentPoint,
                                  mCellmlFileRuntime->statesCount(),
                                  mData->constants(), mData->states(),
                                  mData->rates(), mData->algebraic(),
                                  mCellmlFileRuntime->computeRates());
        } else {
            daeSolver->setProperties(mData->daeSolverProperties());

            daeSolver->initialize(currentPoint, endingPoint,
                                  mCellmlFileRuntime->statesCount(),
                                  mCellmlFileRuntime->condVarCount(),
                                  mData->constants(), mData->states(),
                                  mData->rates(), mData->algebraic(),
                                  mData->condVar(),
                                  mCellmlFileRuntime->computeEssentialVariables(),
                                  mCellmlFileRuntime->computeResiduals(),
                                  mCellmlFileRuntime->computeRootInformation(),
                                  mCellmlFileRuntime->computeStateInformation());
        }

        // Initialise our NLA solver
//---GRY--- CHECK do_nonlinearsolve() IN compilermath.cpp SINCE IT ISN'T
//          CURRENTLY NEEDED. HOWEVER, OUR CURRENT APPROACH IS NOT NICE AND WE
//          REALLY SHOULD INITIALISE THINGS HERE...

        if (mCellmlFileRuntime->needNlaSolver()) {
            CoreSolver::globalNlaSolver()->setProperties(mData->nlaSolverProperties());

//            CoreSolver::globalNlaSolver()->initialize(...);
        }

        // Now, we are ready to compute our model, but only if no error has
        // occurred so far

        if (!mError) {
            // Start our timer

            QTime timer;
            int totalElapsedTime = 0;

            timer.start();

            // Our main work loop
QString states;
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ",STATES["+QString::number(i)+"]";
    else
        states = "STATES["+QString::number(i)+"]";
qDebug("time,%s", qPrintable(states));

            while (   (currentPoint != endingPoint) && !mError
                   && (mStatus != Stopped)) {
                // Handle our current point after making sure that all the
                // variables have been computed

                mCellmlFileRuntime->computeVariables()(currentPoint,
                                                       mData->constants(),
                                                       mData->rates(),
                                                       mData->states(),
                                                       mData->algebraic());

//---GRY--- TO BE DONE...
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ","+QString::number(mData->states()[i]);
    else
        states = QString::number(mData->states()[i]);
qDebug("%f,%s", currentPoint, qPrintable(states));

                // Let people know about our progress

                updateAndEmitProgress((currentPoint-startingPoint)*oneOverPointRange);

                // Check whether we should be pausing

                if(mStatus == Pausing) {
                    // We have been asked to pause, so do just that after stopping
                    // our timer

                    totalElapsedTime += timer.elapsed();

                    mStatusMutex.lock();
                        mStatusCondition.wait(&mStatusMutex);
                    mStatusMutex.unlock();

                    // We are running again

                    mStatus = Running;

                    // Let people know that we are running again

                    emit running();

                    // Restart our timer

                    timer.restart();
                }

                // Determine our next point and compute our model up to it

                ++voiCounter;

                voiSolver->solve(currentPoint,
                                 increasingPoints?
                                     qMin(endingPoint, startingPoint+voiCounter*pointInterval):
                                     qMax(endingPoint, startingPoint+voiCounter*pointInterval));

                // Delay things a bit, if (really) needed

                if (mData->delay() && (mStatus != Stopped)) {
                    totalElapsedTime += timer.elapsed();

                    static_cast<Core::Thread *>(thread())->msleep(mData->delay());

                    timer.restart();
                }
            }

            if (!mError && (mStatus != Stopped)) {
                // Handle our last point

//---GRY--- TO BE DONE...
for (int i = 0, iMax = mCellmlFileRuntime->statesCount(); i < iMax; ++i)
    if (i)
        states += ","+QString::number(mData->states()[i]);
    else
        states = QString::number(mData->states()[i]);
qDebug("%f,%s", currentPoint, qPrintable(states));

                // Let people know about our final progress, but only if we didn't stop
                // the simulation

                updateAndEmitProgress(1.0);
            }

            // Reset our progress
            // Note: we would normally use updateAndEmitProgress(), but we don't
            //       want to emit the progress, so...

            mProgress = 0.0;

            // Retrieve the total elapsed time

            if (!mError)
                totalElapsedTime += timer.elapsed();

            // We are done, so...

            mStatus = Finished;

            // Let people know that we are done and give them the total elapsed time too

            emit finished(mError?-1:totalElapsedTime);
            // Note: we use -1 as a way to indicate that something went wrong...
        } else {
            // An error occurred, so...

            mStatus = Finished;

            // Let people know that we are done
            // Note: we use -1 as a way to indicate that something went wrong...

            emit finished(-1);
        }

        // Delete our solver(s)

        delete odeSolver;
        delete daeSolver;

        CoreSolver::resetGlobalNlaSolver();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::pause()
{
    // Pause ourselves, but only if we are currently running

    if (mStatus == Running) {
        // We are pausing

        mStatus = Pausing;

        // Let people know that we are pausing

        emit pausing();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::resume()
{
    // Resume ourselves, but only if are currently pausing

    if (mStatus == Pausing) {
        // Actually resume ourselves

        mStatusCondition.wakeAll();

        // We are running again

        mStatus = Running;

        // Let people know that we are running again

        emit running();
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::stop()
{
    // Check that we are either running or pausing

    if ((mStatus == Running) || (mStatus == Pausing)) {
        // Resume ourselves, if needed

        if (mStatus == Pausing)
            mStatusCondition.wakeAll();

        // Stop ourselves

        mStatus = Stopped;
    }
}

//==============================================================================

void SingleCellSimulationViewSimulationWorker::emitError(const QString &pMessage)
{
    // A solver error occurred, so keep track of it and let people know about it

    mError = true;

    emit error(pMessage);
}

//==============================================================================

}   // namespace SingleCellSimulationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/**
 * @file llsecapi_test.cpp
 * @author Roxie
 * @date 2009-02-10
 * @brief Test the sec api functionality
 *
 * $LicenseInfo:firstyear=2009&license=viewergpl$
 *
 * Copyright (c) 2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden LregisterSecAPIab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */
#include "../llviewerprecompiledheaders.h"
#include "../llviewernetwork.h"
#include "../test/lltut.h"
#include "../llsecapi.h"
#include "../../llxml/llcontrol.h"

//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing

LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
BOOL LLControlGroup::declareString(const std::string& name,
                                   const std::string& initial_val,
                                   const std::string& comment,
                                   BOOL persist) {return TRUE;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string LLControlGroup::getString(const std::string& name)
{
	return "";
}

LLControlGroup gSavedSettings("test");
class LLSecAPIBasicHandler : public LLSecAPIHandler
{
protected:
	LLPointer<LLCertificateChain> mCertChain;
	LLPointer<LLCertificate> mCert;
	LLPointer<LLCertificateStore> mCertStore;
	LLSD mLLSD;

public:
	LLSecAPIBasicHandler() {}

	virtual ~LLSecAPIBasicHandler() {}

	// instantiate a certificate from a pem string
	virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert)
	{
		return mCert;
	}

	// instiate a certificate from an openssl X509 structure
	virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert)
	{
		return mCert;
	}

	// instantiate a chain from an X509_STORE_CTX
	virtual LLPointer<LLCertificateChain> getCertificateChain(const X509_STORE_CTX* chain)
	{
		return mCertChain;
	}

	// instantiate a cert store given it's id.  if a persisted version
	// exists, it'll be loaded.  If not, one will be created (but not
	// persisted)
	virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id)
	{
		return mCertStore;
	}

	// persist data in a protected store
	virtual void setProtectedData(const std::string& data_type,
								  const std::string& data_id,
								  const LLSD& data) {}

	// retrieve protected data
	virtual LLSD getProtectedData(const std::string& data_type,
								  const std::string& data_id)
	{
		return mLLSD;
	}

	virtual void deleteProtectedData(const std::string& data_type,
									 const std::string& data_id)
	{
	}

	virtual LLPointer<LLCredential> createCredential(const std::string& grid,
													 const LLSD& identifier,
													 const LLSD& authenticator)
	{
		LLPointer<LLCredential> cred = NULL;
		return cred;
	}

	virtual LLPointer<LLCredential> loadCredential(const std::string& grid)
	{
		LLPointer<LLCredential> cred = NULL;
		return cred;
	}

	virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}

	virtual void deleteCredential(LLPointer<LLCredential> cred) {}
};

// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
	// Test wrapper declaration : wrapping nothing for the moment
	struct secapiTest
	{

		secapiTest()
		{
		}
		~secapiTest()
		{
		}
	};

	// Tut templating thingamagic: test group, object and test instance
	typedef test_group<secapiTest> secapiTestFactory;
	typedef secapiTestFactory::object secapiTestObject;
	tut::secapiTestFactory tut_test("llsecapi");

	// ---------------------------------------------------------------------------------------
	// Test functions
	// ---------------------------------------------------------------------------------------
	// registration
	template<> template<>
	void secapiTestObject::test<1>()
	{
		// retrieve an unknown handler

		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		LLPointer<LLSecAPIHandler> test1_handler =  new LLSecAPIBasicHandler();
		registerSecHandler("sectest1", test1_handler);
		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		LLPointer<LLSecAPIHandler> retrieved_test1_handler = getSecHandler("sectest1");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test1_handler == test1_handler);

		// insert a second handler
		LLPointer<LLSecAPIHandler> test2_handler =  new LLSecAPIBasicHandler();
		registerSecHandler("sectest2", test2_handler);
		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		retrieved_test1_handler = getSecHandler("sectest1");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test1_handler == test1_handler);

		LLPointer<LLSecAPIHandler> retrieved_test2_handler = getSecHandler("sectest2");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test2_handler == test2_handler);

	}
}
<commit_msg>Fix for SNOW-742 compile & link errors under certain gcc versions due to violation of One Definition Rule. reviewed by Moss.<commit_after>/**
 * @file llsecapi_test.cpp
 * @author Roxie
 * @date 2009-02-10
 * @brief Test the sec api functionality
 *
 * $LicenseInfo:firstyear=2009&license=viewergpl$
 *
 * Copyright (c) 2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden LregisterSecAPIab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */
#include "../llviewerprecompiledheaders.h"
#include "../llviewernetwork.h"
#include "../test/lltut.h"
#include "../llsecapi.h"
#include "../llsechandler_basic.h"
#include "../../llxml/llcontrol.h"

//----------------------------------------------------------------------------
// Mock objects for the dependencies of the code we're testing

LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
BOOL LLControlGroup::declareString(const std::string& name,
                                   const std::string& initial_val,
                                   const std::string& comment,
                                   BOOL persist) {return TRUE;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string LLControlGroup::getString(const std::string& name)
{
	return "";
}

LLControlGroup gSavedSettings("test");

LLSecAPIBasicHandler::LLSecAPIBasicHandler() {}
void LLSecAPIBasicHandler::init() {}
LLSecAPIBasicHandler::~LLSecAPIBasicHandler() {}
LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert) { return NULL; }
LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert) { return NULL; }
LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; }
LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; }
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; }
void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {}

// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
namespace tut
{
	// Test wrapper declaration : wrapping nothing for the moment
	struct secapiTest
	{

		secapiTest()
		{
		}
		~secapiTest()
		{
		}
	};

	// Tut templating thingamagic: test group, object and test instance
	typedef test_group<secapiTest> secapiTestFactory;
	typedef secapiTestFactory::object secapiTestObject;
	tut::secapiTestFactory tut_test("llsecapi");

	// ---------------------------------------------------------------------------------------
	// Test functions
	// ---------------------------------------------------------------------------------------
	// registration
	template<> template<>
	void secapiTestObject::test<1>()
	{
		// retrieve an unknown handler

		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		LLPointer<LLSecAPIHandler> test1_handler =  new LLSecAPIBasicHandler();
		registerSecHandler("sectest1", test1_handler);
		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		LLPointer<LLSecAPIHandler> retrieved_test1_handler = getSecHandler("sectest1");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test1_handler == test1_handler);

		// insert a second handler
		LLPointer<LLSecAPIHandler> test2_handler =  new LLSecAPIBasicHandler();
		registerSecHandler("sectest2", test2_handler);
		ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown"));
		retrieved_test1_handler = getSecHandler("sectest1");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test1_handler == test1_handler);

		LLPointer<LLSecAPIHandler> retrieved_test2_handler = getSecHandler("sectest2");
		ensure("Retrieved sectest1 handler should be the same",
			   retrieved_test2_handler == test2_handler);

	}
}
<|endoftext|>


<commit_before>//===-- XCoreISelDAGToDAG.cpp - A dag to dag inst selector for XCore ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the XCore target.
//
//===----------------------------------------------------------------------===//

#include "XCore.h"
#include "XCoreTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;

/// XCoreDAGToDAGISel - XCore specific code to select XCore machine
/// instructions for SelectionDAG operations.
///
namespace {
  class XCoreDAGToDAGISel : public SelectionDAGISel {

  public:
    XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOpt::Level OptLevel)
      : SelectionDAGISel(TM, OptLevel) {}

    SDNode *SelectImpl(SDNode *N) override;
    SDNode *SelectBRIND(SDNode *N);

    /// getI32Imm - Return a target constant with the specified value, of type
    /// i32.
    inline SDValue getI32Imm(unsigned Imm, SDLoc dl) {
      return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
    }

    inline bool immMskBitp(SDNode *inN) const {
      ConstantSDNode *N = cast<ConstantSDNode>(inN);
      uint32_t value = (uint32_t)N->getZExtValue();
      if (!isMask_32(value)) {
        return false;
      }
      int msksize = 32 - countLeadingZeros(value);
      return (msksize >= 1 && msksize <= 8) ||
              msksize == 16 || msksize == 24 || msksize == 32;
    }

    // Complex Pattern Selectors.
    bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);

    bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
                                      std::vector<SDValue> &OutOps) override;

    const char *getPassName() const override {
      return "XCore DAG->DAG Pattern Instruction Selection";
    }

    // Include the pieces autogenerated from the target description.
  #include "XCoreGenDAGISel.inc"
  };
}  // end anonymous namespace

/// createXCoreISelDag - This pass converts a legalized DAG into a
/// XCore-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM,
                                       CodeGenOpt::Level OptLevel) {
  return new XCoreDAGToDAGISel(TM, OptLevel);
}

bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
                                       SDValue &Offset) {
  FrameIndexSDNode *FIN = nullptr;
  if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
    return true;
  }
  if (Addr.getOpcode() == ISD::ADD) {
    ConstantSDNode *CN = nullptr;
    if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
      && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
      // Constant positive word offset from frame index
      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
      Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
                                         MVT::i32);
      return true;
    }
  }
  return false;
}

bool XCoreDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
                             std::vector<SDValue> &OutOps) {
  SDValue Reg;
  switch (ConstraintID) {
  default: return true;
  case InlineAsm::Constraint_m: // Memory.
    switch (Op.getOpcode()) {
    default: return true;
    case XCoreISD::CPRelativeWrapper:
      Reg = CurDAG->getRegister(XCore::CP, MVT::i32);
      break;
    case XCoreISD::DPRelativeWrapper:
      Reg = CurDAG->getRegister(XCore::DP, MVT::i32);
      break;
    }
  }
  OutOps.push_back(Reg);
  OutOps.push_back(Op.getOperand(0));
  return false;
}

SDNode *XCoreDAGToDAGISel::SelectImpl(SDNode *N) {
  SDLoc dl(N);
  switch (N->getOpcode()) {
  default: break;
  case ISD::Constant: {
    uint64_t Val = cast<ConstantSDNode>(N)->getZExtValue();
    if (immMskBitp(N)) {
      // Transformation function: get the size of a mask
      // Look for the first non-zero bit
      SDValue MskSize = getI32Imm(32 - countLeadingZeros((uint32_t)Val), dl);
      return CurDAG->getMachineNode(XCore::MKMSK_rus, dl,
                                    MVT::i32, MskSize);
    }
    else if (!isUInt<16>(Val)) {
      SDValue CPIdx = CurDAG->getTargetConstantPool(
          ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val),
          getTargetLowering()->getPointerTy(CurDAG->getDataLayout()));
      SDNode *node = CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32,
                                            MVT::Other, CPIdx,
                                            CurDAG->getEntryNode());
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] =
          MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(*MF),
                                   MachineMemOperand::MOLoad, 4, 4);
      cast<MachineSDNode>(node)->setMemRefs(MemOp, MemOp + 1);
      return node;
    }
    break;
  }
  case XCoreISD::LADD: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                        N->getOperand(2) };
    return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case XCoreISD::LSUB: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                        N->getOperand(2) };
    return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case XCoreISD::MACCU: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case XCoreISD::MACCS: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case XCoreISD::LMUL: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case XCoreISD::CRC8: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
    return CurDAG->getMachineNode(XCore::CRC8_l4r, dl, MVT::i32, MVT::i32,
                                  Ops);
  }
  case ISD::BRIND:
    if (SDNode *ResNode = SelectBRIND(N))
      return ResNode;
    break;
  // Other cases are autogenerated.
  }
  return SelectCode(N);
}

/// Given a chain return a new chain where any appearance of Old is replaced
/// by New. There must be at most one instruction between Old and Chain and
/// this instruction must be a TokenFactor. Returns an empty SDValue if
/// these conditions don't hold.
static SDValue
replaceInChain(SelectionDAG *CurDAG, SDValue Chain, SDValue Old, SDValue New)
{
  if (Chain == Old)
    return New;
  if (Chain->getOpcode() != ISD::TokenFactor)
    return SDValue();
  SmallVector<SDValue, 8> Ops;
  bool found = false;
  for (unsigned i = 0, e = Chain->getNumOperands(); i != e; ++i) {
    if (Chain->getOperand(i) == Old) {
      Ops.push_back(New);
      found = true;
    } else {
      Ops.push_back(Chain->getOperand(i));
    }
  }
  if (!found)
    return SDValue();
  return CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, Ops);
}

SDNode *XCoreDAGToDAGISel::SelectBRIND(SDNode *N) {
  SDLoc dl(N);
  // (brind (int_xcore_checkevent (addr)))
  SDValue Chain = N->getOperand(0);
  SDValue Addr = N->getOperand(1);
  if (Addr->getOpcode() != ISD::INTRINSIC_W_CHAIN)
    return nullptr;
  unsigned IntNo = cast<ConstantSDNode>(Addr->getOperand(1))->getZExtValue();
  if (IntNo != Intrinsic::xcore_checkevent)
    return nullptr;
  SDValue nextAddr = Addr->getOperand(2);
  SDValue CheckEventChainOut(Addr.getNode(), 1);
  if (!CheckEventChainOut.use_empty()) {
    // If the chain out of the checkevent intrinsic is an operand of the
    // indirect branch or used in a TokenFactor which is the operand of the
    // indirect branch then build a new chain which uses the chain coming into
    // the checkevent intrinsic instead.
    SDValue CheckEventChainIn = Addr->getOperand(0);
    SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut,
                                      CheckEventChainIn);
    if (!NewChain.getNode())
      return nullptr;
    Chain = NewChain;
  }
  // Enable events on the thread using setsr 1 and then disable them immediately
  // after with clrsr 1. If any resources owned by the thread are ready an event
  // will be taken. If no resource is ready we branch to the address which was
  // the operand to the checkevent intrinsic.
  SDValue constOne = getI32Imm(1, dl);
  SDValue Glue =
    SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue,
                                   constOne, Chain), 0);
  Glue =
    SDValue(CurDAG->getMachineNode(XCore::CLRSR_branch_u6, dl, MVT::Glue,
                                   constOne, Glue), 0);
  if (nextAddr->getOpcode() == XCoreISD::PCRelativeWrapper &&
      nextAddr->getOperand(0)->getOpcode() == ISD::TargetBlockAddress) {
    return CurDAG->SelectNodeTo(N, XCore::BRFU_lu6, MVT::Other,
                                nextAddr->getOperand(0), Glue);
  }
  return CurDAG->SelectNodeTo(N, XCore::BAU_1r, MVT::Other, nextAddr, Glue);
}
<commit_msg>SDAG: Implement Select instead of SelectImpl in XCoreDAGToDAGISel<commit_after>//===-- XCoreISelDAGToDAG.cpp - A dag to dag inst selector for XCore ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the XCore target.
//
//===----------------------------------------------------------------------===//

#include "XCore.h"
#include "XCoreTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;

/// XCoreDAGToDAGISel - XCore specific code to select XCore machine
/// instructions for SelectionDAG operations.
///
namespace {
  class XCoreDAGToDAGISel : public SelectionDAGISel {

  public:
    XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOpt::Level OptLevel)
      : SelectionDAGISel(TM, OptLevel) {}

    void Select(SDNode *N) override;
    bool tryBRIND(SDNode *N);

    /// getI32Imm - Return a target constant with the specified value, of type
    /// i32.
    inline SDValue getI32Imm(unsigned Imm, SDLoc dl) {
      return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
    }

    inline bool immMskBitp(SDNode *inN) const {
      ConstantSDNode *N = cast<ConstantSDNode>(inN);
      uint32_t value = (uint32_t)N->getZExtValue();
      if (!isMask_32(value)) {
        return false;
      }
      int msksize = 32 - countLeadingZeros(value);
      return (msksize >= 1 && msksize <= 8) ||
              msksize == 16 || msksize == 24 || msksize == 32;
    }

    // Complex Pattern Selectors.
    bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);

    bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
                                      std::vector<SDValue> &OutOps) override;

    const char *getPassName() const override {
      return "XCore DAG->DAG Pattern Instruction Selection";
    }

    // Include the pieces autogenerated from the target description.
  #include "XCoreGenDAGISel.inc"
  };
}  // end anonymous namespace

/// createXCoreISelDag - This pass converts a legalized DAG into a
/// XCore-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM,
                                       CodeGenOpt::Level OptLevel) {
  return new XCoreDAGToDAGISel(TM, OptLevel);
}

bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
                                       SDValue &Offset) {
  FrameIndexSDNode *FIN = nullptr;
  if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
    return true;
  }
  if (Addr.getOpcode() == ISD::ADD) {
    ConstantSDNode *CN = nullptr;
    if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
      && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
      // Constant positive word offset from frame index
      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
      Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
                                         MVT::i32);
      return true;
    }
  }
  return false;
}

bool XCoreDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
                             std::vector<SDValue> &OutOps) {
  SDValue Reg;
  switch (ConstraintID) {
  default: return true;
  case InlineAsm::Constraint_m: // Memory.
    switch (Op.getOpcode()) {
    default: return true;
    case XCoreISD::CPRelativeWrapper:
      Reg = CurDAG->getRegister(XCore::CP, MVT::i32);
      break;
    case XCoreISD::DPRelativeWrapper:
      Reg = CurDAG->getRegister(XCore::DP, MVT::i32);
      break;
    }
  }
  OutOps.push_back(Reg);
  OutOps.push_back(Op.getOperand(0));
  return false;
}

void XCoreDAGToDAGISel::Select(SDNode *N) {
  SDLoc dl(N);
  switch (N->getOpcode()) {
  default: break;
  case ISD::Constant: {
    uint64_t Val = cast<ConstantSDNode>(N)->getZExtValue();
    if (immMskBitp(N)) {
      // Transformation function: get the size of a mask
      // Look for the first non-zero bit
      SDValue MskSize = getI32Imm(32 - countLeadingZeros((uint32_t)Val), dl);
      ReplaceNode(N, CurDAG->getMachineNode(XCore::MKMSK_rus, dl,
                                            MVT::i32, MskSize));
      return;
    }
    else if (!isUInt<16>(Val)) {
      SDValue CPIdx = CurDAG->getTargetConstantPool(
          ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val),
          getTargetLowering()->getPointerTy(CurDAG->getDataLayout()));
      SDNode *node = CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32,
                                            MVT::Other, CPIdx,
                                            CurDAG->getEntryNode());
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] =
          MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(*MF),
                                   MachineMemOperand::MOLoad, 4, 4);
      cast<MachineSDNode>(node)->setMemRefs(MemOp, MemOp + 1);
      ReplaceNode(N, node);
      return;
    }
    break;
  }
  case XCoreISD::LADD: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                        N->getOperand(2) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case XCoreISD::LSUB: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                        N->getOperand(2) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case XCoreISD::MACCU: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case XCoreISD::MACCS: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case XCoreISD::LMUL: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                      N->getOperand(2), N->getOperand(3) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case XCoreISD::CRC8: {
    SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
    ReplaceNode(N, CurDAG->getMachineNode(XCore::CRC8_l4r, dl, MVT::i32,
                                          MVT::i32, Ops));
    return;
  }
  case ISD::BRIND:
    if (tryBRIND(N))
      return;
    break;
  // Other cases are autogenerated.
  }
  SelectCode(N);
}

/// Given a chain return a new chain where any appearance of Old is replaced
/// by New. There must be at most one instruction between Old and Chain and
/// this instruction must be a TokenFactor. Returns an empty SDValue if
/// these conditions don't hold.
static SDValue
replaceInChain(SelectionDAG *CurDAG, SDValue Chain, SDValue Old, SDValue New)
{
  if (Chain == Old)
    return New;
  if (Chain->getOpcode() != ISD::TokenFactor)
    return SDValue();
  SmallVector<SDValue, 8> Ops;
  bool found = false;
  for (unsigned i = 0, e = Chain->getNumOperands(); i != e; ++i) {
    if (Chain->getOperand(i) == Old) {
      Ops.push_back(New);
      found = true;
    } else {
      Ops.push_back(Chain->getOperand(i));
    }
  }
  if (!found)
    return SDValue();
  return CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, Ops);
}

bool XCoreDAGToDAGISel::tryBRIND(SDNode *N) {
  SDLoc dl(N);
  // (brind (int_xcore_checkevent (addr)))
  SDValue Chain = N->getOperand(0);
  SDValue Addr = N->getOperand(1);
  if (Addr->getOpcode() != ISD::INTRINSIC_W_CHAIN)
    return false;
  unsigned IntNo = cast<ConstantSDNode>(Addr->getOperand(1))->getZExtValue();
  if (IntNo != Intrinsic::xcore_checkevent)
    return false;
  SDValue nextAddr = Addr->getOperand(2);
  SDValue CheckEventChainOut(Addr.getNode(), 1);
  if (!CheckEventChainOut.use_empty()) {
    // If the chain out of the checkevent intrinsic is an operand of the
    // indirect branch or used in a TokenFactor which is the operand of the
    // indirect branch then build a new chain which uses the chain coming into
    // the checkevent intrinsic instead.
    SDValue CheckEventChainIn = Addr->getOperand(0);
    SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut,
                                      CheckEventChainIn);
    if (!NewChain.getNode())
      return false;
    Chain = NewChain;
  }
  // Enable events on the thread using setsr 1 and then disable them immediately
  // after with clrsr 1. If any resources owned by the thread are ready an event
  // will be taken. If no resource is ready we branch to the address which was
  // the operand to the checkevent intrinsic.
  SDValue constOne = getI32Imm(1, dl);
  SDValue Glue =
    SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue,
                                   constOne, Chain), 0);
  Glue =
    SDValue(CurDAG->getMachineNode(XCore::CLRSR_branch_u6, dl, MVT::Glue,
                                   constOne, Glue), 0);
  if (nextAddr->getOpcode() == XCoreISD::PCRelativeWrapper &&
      nextAddr->getOperand(0)->getOpcode() == ISD::TargetBlockAddress) {
    CurDAG->SelectNodeTo(N, XCore::BRFU_lu6, MVT::Other,
                         nextAddr->getOperand(0), Glue);
    return true;
  }
  CurDAG->SelectNodeTo(N, XCore::BAU_1r, MVT::Other, nextAddr, Glue);
  return true;
}
<|endoftext|>


<commit_before>//===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements constant propagation and merging:
//
// Specifically, this:
//   * Converts instructions like "add int 1, 2" into 3
//
// Notice that:
//   * This pass has a habit of making definitions be dead.  It is a good idea
//     to to run a DIE pass sometime after running this pass.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constant.h"
#include "llvm/Instruction.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h"
#include "Support/Statistic.h"
#include <set>
using namespace llvm;

namespace {
  Statistic<> NumInstKilled("constprop", "Number of instructions killed");

  struct ConstantPropagation : public FunctionPass {
    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
    }
  };

  RegisterOpt<ConstantPropagation> X("constprop","Simple constant propagation");
}

Pass *llvm::createConstantPropagationPass() {
  return new ConstantPropagation();
}

bool ConstantPropagation::runOnFunction(Function &F) {
  // Initialize the worklist to all of the instructions ready to process...
  std::set<Instruction*> WorkList(inst_begin(F), inst_end(F));
  bool Changed = false;

  while (!WorkList.empty()) {
    Instruction *I = *WorkList.begin();
    WorkList.erase(WorkList.begin());    // Get an element from the worklist...

    if (!I->use_empty())                 // Don't muck with dead instructions...
      if (Constant *C = ConstantFoldInstruction(I)) {
        // Add all of the users of this instruction to the worklist, they might
        // be constant propagatable now...
        for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
             UI != UE; ++UI)
          WorkList.insert(cast<Instruction>(*UI));

        // Replace all of the uses of a variable with uses of the constant.
        I->replaceAllUsesWith(C);

        // We made a change to the function...
        Changed = true;
        ++NumInstKilled;
      }
  }
  return Changed;
}
<commit_msg>Constant propagation should remove the dead instructions<commit_after>//===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements constant propagation and merging:
//
// Specifically, this:
//   * Converts instructions like "add int 1, 2" into 3
//
// Notice that:
//   * This pass has a habit of making definitions be dead.  It is a good idea
//     to to run a DIE pass sometime after running this pass.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constant.h"
#include "llvm/Instruction.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h"
#include "Support/Statistic.h"
#include <set>
using namespace llvm;

namespace {
  Statistic<> NumInstKilled("constprop", "Number of instructions killed");

  struct ConstantPropagation : public FunctionPass {
    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
    }
  };

  RegisterOpt<ConstantPropagation> X("constprop","Simple constant propagation");
}

Pass *llvm::createConstantPropagationPass() {
  return new ConstantPropagation();
}

bool ConstantPropagation::runOnFunction(Function &F) {
  // Initialize the worklist to all of the instructions ready to process...
  std::set<Instruction*> WorkList(inst_begin(F), inst_end(F));
  bool Changed = false;

  while (!WorkList.empty()) {
    Instruction *I = *WorkList.begin();
    WorkList.erase(WorkList.begin());    // Get an element from the worklist...

    if (!I->use_empty())                 // Don't muck with dead instructions...
      if (Constant *C = ConstantFoldInstruction(I)) {
        // Add all of the users of this instruction to the worklist, they might
        // be constant propagatable now...
        for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
             UI != UE; ++UI)
          WorkList.insert(cast<Instruction>(*UI));

        // Replace all of the uses of a variable with uses of the constant.
        I->replaceAllUsesWith(C);

        // Remove the dead instruction.
        WorkList.erase(I);
        I->getParent()->getInstList().erase(I);

        // We made a change to the function...
        Changed = true;
        ++NumInstKilled;
      }
  }
  return Changed;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/TranscodingException.hpp>
#include <util/XMLString.hpp>
#include <util/XMLUTF8Transcoder.hpp>
#include <util/UTFDataFormatException.hpp>

// ---------------------------------------------------------------------------
//  Local static data
//
//  gUTFBytes
//      A list of counts of trailing bytes for each initial byte in the input.
//
//  gUTFOffsets
//      A list of values to offset each result char type, according to how
//      many source bytes when into making it.
//
//  gFirstByteMark
//      A list of values to mask onto the first byte of an encoded sequence,
//      indexed by the number of bytes used to create the sequence.
// ---------------------------------------------------------------------------
static const XMLByte gUTFBytes[256] =
{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    ,   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    ,   3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
};

static const XMLUInt32 gUTFOffsets[6] =
{
    0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080
};

static const XMLByte gFirstByteMark[7] =
{
    0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
};

// ---------------------------------------------------------------------------
//  XMLUTF8Transcoder: Constructors and Destructor
// ---------------------------------------------------------------------------
XMLUTF8Transcoder::XMLUTF8Transcoder(const  XMLCh* const    encodingName
                                    , const unsigned int    blockSize) :

    XMLTranscoder(encodingName, blockSize)
{
}

XMLUTF8Transcoder::~XMLUTF8Transcoder()
{
}

// ---------------------------------------------------------------------------
//  XMLUTF8Transcoder: Implementation of the transcoder API
// ---------------------------------------------------------------------------
unsigned int
XMLUTF8Transcoder::transcodeFrom(const  XMLByte* const          srcData
                                , const unsigned int            srcCount
                                ,       XMLCh* const            toFill
                                , const unsigned int            maxChars
                                ,       unsigned int&           bytesEaten
                                ,       unsigned char* const    charSizes)
{
    // Watch for pathological scenario. Shouldn't happen, but...
    if (!srcCount || !maxChars)
        return 0;

    // If debugging, make sure that the block size is legal
    #if defined(XERCES_DEBUG)
    checkBlockSize(maxChars);
    #endif

    //
    //  Get pointers to our start and end points of the input and output
    //  buffers.
    //
    const XMLByte*  srcPtr = srcData;
    const XMLByte*  srcEnd = srcPtr + srcCount;
    XMLCh*          outPtr = toFill;
    XMLCh*          outEnd = outPtr + maxChars;
    unsigned char*  sizePtr = charSizes;

    //
    //  We now loop until we either run out of input data, or room to store
    //  output chars.
    //
    while ((srcPtr < srcEnd) && (outPtr < outEnd))
    {
        // Get the next leading byte out
        const XMLByte firstByte = *srcPtr;

        // Special-case ASCII, which is a leading byte value of <= 127
        if (firstByte <= 127)
        {
            *outPtr++ = XMLCh(firstByte);
            srcPtr++;
            *sizePtr++ = 1;
            continue;
        }

        // See how many trailing src bytes this sequence is going to require
        const unsigned int trailingBytes = gUTFBytes[firstByte];

        //
        //  If there are not enough source bytes to do this one, then we
        //  are done. Note that we done >= here because we are implicitly
        //  counting the 1 byte we get no matter what.
        //
        //  If we break out here, then there is nothing to undo since we
        //  haven't updated any pointers yet.
        //
        if (srcPtr + trailingBytes >= srcEnd)
            break;

        // Looks ok, so lets build up the value
        XMLUInt32 tmpVal = 0;
        switch(trailingBytes)
        {
            case 5 : tmpVal += *srcPtr++; tmpVal <<= 6;
            case 4 : tmpVal += *srcPtr++; tmpVal <<= 6;
            case 3 : tmpVal += *srcPtr++; tmpVal <<= 6;
            case 2 : tmpVal += *srcPtr++; tmpVal <<= 6;
            case 1 : tmpVal += *srcPtr++; tmpVal <<= 6;
            case 0 : tmpVal += *srcPtr++;
                     break;

            default :
                ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
        }
        tmpVal -= gUTFOffsets[trailingBytes];

        //
        //  If it will fit into a single char, then put it in. Otherwise
        //  encode it as a surrogate pair. If its not valid, use the
        //  replacement char.
        //
        if (!(tmpVal & 0xFFFF0000))
        {
            *sizePtr++ = trailingBytes + 1;
            *outPtr++ = XMLCh(tmpVal);
        }
         else if (tmpVal > 0x10FFFF)
        {
            //
            //  If we've gotten more than 32 chars so far, then just break
            //  out for now and lets process those. When we come back in
            //  here again, we'll get no chars and throw an exception. This
            //  way, the error will have a line and col number closer to
            //  the real problem area.
            //
            if ((outPtr - toFill) > 32)
                break;

            ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
        }
         else
        {
            //
            //  If we have enough room to store the leading and trailing
            //  chars, then lets do it. Else, pretend this one never
            //  happened, and leave it for the next time. Since we don't
            //  update the bytes read until the bottom of the loop, by
            //  breaking out here its like it never happened.
            //
            if (outPtr + 1 >= outEnd)
                break;

            // Store the leading surrogate char
            tmpVal -= 0x10000;
            *sizePtr++ = trailingBytes + 1;
            *outPtr++ = XMLCh((tmpVal >> 10) + 0xD800);

            //
            //  And then the treailing char. This one accounts for no
            //  bytes eaten from the source, so set the char size for this
            //  one to be zero.
            //
            *sizePtr++ = 0;
            *outPtr++ = XMLCh(tmpVal & 0x3FF) + 0xDC00;
        }
    }

    // Update the bytes eaten
    bytesEaten = srcPtr - srcData;

    // Return the characters read
    return outPtr - toFill;
}

unsigned int
XMLUTF8Transcoder::transcodeTo( const   XMLCh* const    srcData
                                , const unsigned int    srcCount
                                ,       XMLByte* const  toFill
                                , const unsigned int    maxBytes
                                ,       unsigned int&   charsEaten
                                , const UnRepOpts       options)
{
    // Watch for pathological scenario. Shouldn't happen, but...
    if (!srcCount || !maxBytes)
        return 0;

    //
    //  Get pointers to our start and end points of the input and output
    //  buffers.
    //
    const XMLCh*    srcPtr = srcData;
    const XMLCh*    srcEnd = srcPtr + srcCount;
    XMLByte*        outPtr = toFill;
    XMLByte*        outEnd = toFill + maxBytes;

    while (srcPtr < srcEnd)
    {
        //
        //  Tentatively get the next char out. We have to get it into a
        //  32 bit value, because it could be a surrogate pair.
        //
        XMLUInt32 curVal = *srcPtr;

        //
        //  If its a leading surrogate, then lets see if we have the trailing
        //  available. If not, then give up now and leave it for next time.
        //
        unsigned int srcUsed = 1;
        if ((curVal >= 0xD800) && (curVal <= 0xDBFF))
        {
            if (srcPtr + 1 >= srcEnd)
                break;

            // Create the composite surrogate pair
            curVal = ((curVal - 0xD800) << 10)
                    + ((*(srcPtr + 1) - 0xDC00) + 0x10000);

            // And indicate that we ate another one
            srcUsed++;
        }

        // Figure out how many bytes we need
        unsigned int encodedBytes;
        if (curVal < 0x80)
            encodedBytes = 1;
        else if (curVal < 0x800)
            encodedBytes = 2;
        else if (curVal < 0x10000)
            encodedBytes = 3;
        else if (curVal < 0x200000)
            encodedBytes = 4;
        else if (curVal < 0x4000000)
            encodedBytes = 5;
        else if (curVal <= 0x7FFFFFFF)
            encodedBytes = 6;
        else
        {
            // If the options say to throw, then throw
            if (options == UnRep_Throw)
            {
                XMLCh tmpBuf[16];
                XMLString::binToText(curVal, tmpBuf, 16, 16);
                ThrowXML2
                (
                    TranscodingException
                    , XMLExcepts::Trans_Unrepresentable
                    , tmpBuf
                    , getEncodingName()
                );
            }

            // Else, use the replacement character
            *outPtr++ = chSpace;
            srcPtr += srcUsed;
            continue;
        }

        //
        //  If we cannot fully get this char into the output buffer,
        //  then leave it for the next time.
        //
        if (outPtr + encodedBytes > outEnd)
            break;

        // We can do it, so update the source index
        srcPtr += srcUsed;

        //
        //  And spit out the bytes. We spit them out in reverse order
        //  here, so bump up the output pointer and work down as we go.
        //
        outPtr += encodedBytes;
        switch(encodedBytes)
        {
            case 6 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 5 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 4 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 3 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 2 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 1 : *--outPtr = XMLByte
                     (
                        curVal | gFirstByteMark[encodedBytes]
                     );
        }

        // Add the encoded bytes back in again to indicate we've eaten them
        outPtr += encodedBytes;
    }

    // Fill in the chars we ate
    charsEaten = (srcPtr - srcData);

    // And return the bytes we filled in
    return (outPtr - toFill);
}

bool XMLUTF8Transcoder::canTranscodeTo(const unsigned int toCheck) const
{
    // We can represent anything in the Unicode (with surrogates) range
    return (toCheck <= 0x10FFFF);
}
<commit_msg>Undo inadvertant remove<commit_after><|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <functional>

// class function<R(ArgTypes...)>

// explicit function();

#include <functional>
#include <cassert>

int main(int, char**)
{
    std::function<int(int)> f;
    assert(!f);

  return 0;
}
<commit_msg>[NFC] Fix incorrect comment in std::function test<commit_after>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <functional>

// class function<R(ArgTypes...)>

// function();

#include <functional>
#include <cassert>

int main(int, char**)
{
    std::function<int(int)> f;
    assert(!f);

  return 0;
}
<|endoftext|>


<commit_before>/////////////////////////////////////
// This C code is a companion to the paper
//
/////////////////////////////////////

//
// this code will hash strings of 64-bit characters. To use on
// strings of 8-bit characters, you may need some adequate padding.
//
#include <cassert>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstdlib>

#include <sys/time.h>

#include <iostream>

using namespace std;

#ifdef __AVX__
#define __PCLMUL__ 1
#endif

extern "C" {
#include "timers.h"

#include "hashfunctions32bits.h"
#include "hashfunctions64bits.h"

#include "clmulhashfunctions32bits.h"
#include "clmulhashfunctions64bits.h"
#include "clmulpoly64bits.h"
#include "clmulhierarchical64bits.h"
#include "ghash.h"
#include "bigendianuniversal.h"
}

#include "treehash/simple-treehash.hh"
#include "treehash/recursive-treehash.hh"
#include "treehash/binary-treehash.hh"
#include "treehash/boosted-treehash.hh"

struct NamedFunc {
  const hashFunction64 f;
  const string name;
  NamedFunc(const hashFunction64& f, const string& name) : f(f), name(name) {}
};

#define NAMED(f) NamedFunc(f, #f)

NamedFunc hashFunctions[] = {
    // From the 2015 paper:
    NAMED(&hashVHASH64), NAMED(&CLHASH), NAMED(&hashCity), NAMED(&hashSipHash),
    NAMED(&GHASH64bit),
    // Horner methods:
    NAMED(&hornerHash), NAMED(&unrolledHorner4), NAMED(&twiceHorner32),
    NAMED(&iterateCL11),
    // Tree hashing:
    NAMED(&treeCL9), NAMED(&simple_treehash), NAMED(&recursive_treehash),
    NAMED(&binary_treehash), NAMED(&boosted_treehash<1>),
    NAMED(&boosted_treehash<2>), NAMED(&boosted_treehash<3>),
    NAMED(&boosted_treehash<4>), NAMED(&boosted_treehash<5>),
    NAMED(&boosted_treehash<6>), NAMED(&boosted_treehash<7>),
    NAMED(&simple_cl_treehash), NAMED(&generic_simple_treehash<MultiplyShift>),
    NAMED(&generic_simple_treehash<NH>), NAMED(&generic_simple_treehash<CLNH>),
    NAMED((&generic_simple_treehash<Wide<MultiplyShift, 15> >)),
    NAMED((&generic_simple_treehash<Wide<NH, 4> >)),
    NAMED((&generic_simple_treehash<Wide<CLNH, 4> >)),
    NAMED((&generic_simple_treehash<Wide<CLNHx2, 4> >)),
};

const int HowManyFunctions64 =
    sizeof(hashFunctions) / sizeof(hashFunctions[0]);

int main(int c, char ** arg) {
    (void) (c);
    (void) (arg);
    uint64_t which_algos = ~0;
    assert(HowManyFunctions64 <= 64);
    if (c > 1) {
      if (1 != sscanf(arg[1], "%" SCNu64, &which_algos)) {
        return 1;
      }
    }
    int lengthStart = 1, lengthEnd = 2048; // inclusive
    if (c > 2)
        lengthStart = atoi(arg[2]);
    if (c > 3)
        lengthEnd = atoi(arg[3]);

    int i, j;
    int length;
    int SHORTTRIALS;
    struct timeval start, finish;
    uint64_t randbuffer[150] __attribute__ ((aligned (16)));// 150 should be plenty
    uint32_t sumToFoolCompiler = 0;
    uint64_t * intstring;
    // We need 32 bytes of alignment for working with __m256i's
    if (posix_memalign((void **)(&intstring), 32, sizeof(uint64_t)*lengthEnd)) {
      cerr << "Failed to allocate " << lengthEnd << " words." << endl;
      return 1;
    }
    for (i = 0; i < 150; ++i) {
        randbuffer[i] = rand() | ((uint64_t)(rand()) << 32);
    }
    for (i = 0; i < lengthEnd; ++i) {
        intstring[i] = rand() | ((uint64_t)(rand()) << 32);
    }
    printf("#Reporting the number of cycles per byte.\n");
    printf("#First number is input length in  8-byte words.\n");
    printf("0 ");
    for (i = 0; i < HowManyFunctions64; ++i) {
        if (which_algos & (0x1ull << i))
          cout << '"' << hashFunctions[i].name << "\" ";
    }
    printf("\n");
    fflush(stdout);
    for (length = lengthStart; length <= lengthEnd; length += 1) {
        SHORTTRIALS = 8000000 / length;
        printf("%8d \t\t", length);

        for (i = 0; i < HowManyFunctions64; ++i) {
            if (!(which_algos & (0x1ull << i)))
                continue;  // skip unselected algos
            const hashFunction64 thisfunc64 = hashFunctions[i].f;
            sumToFoolCompiler += thisfunc64(randbuffer, intstring, length); // we do not count the first one
            gettimeofday(&start, 0);
            ticks lowest = ~(ticks)0;
            for (j = 0; j < SHORTTRIALS; ++j) {
                const ticks bef = startRDTSC();
                sumToFoolCompiler += thisfunc64(randbuffer, intstring, length);
                const ticks aft = stopRDTSCP();
                const ticks diff = aft-bef;
                lowest = (lowest < diff) ? lowest : diff;
            }
            gettimeofday(&finish, 0);
            printf(" %.2f ", lowest * 1.0 / (8.0 * length));
            fflush(stdout);
        }
        printf("\n");
    }
    free(intstring);
    printf("# ignore this #%d\n", sumToFoolCompiler);

}

<commit_msg>Add one more to the precision for fine-tuning<commit_after>/////////////////////////////////////
// This C code is a companion to the paper
//
/////////////////////////////////////

//
// this code will hash strings of 64-bit characters. To use on
// strings of 8-bit characters, you may need some adequate padding.
//
#include <cassert>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstdlib>

#include <sys/time.h>

#include <iostream>

using namespace std;

#ifdef __AVX__
#define __PCLMUL__ 1
#endif

extern "C" {
#include "timers.h"

#include "hashfunctions32bits.h"
#include "hashfunctions64bits.h"

#include "clmulhashfunctions32bits.h"
#include "clmulhashfunctions64bits.h"
#include "clmulpoly64bits.h"
#include "clmulhierarchical64bits.h"
#include "ghash.h"
#include "bigendianuniversal.h"
}

#include "treehash/simple-treehash.hh"
#include "treehash/recursive-treehash.hh"
#include "treehash/binary-treehash.hh"
#include "treehash/boosted-treehash.hh"

struct NamedFunc {
  const hashFunction64 f;
  const string name;
  NamedFunc(const hashFunction64& f, const string& name) : f(f), name(name) {}
};

#define NAMED(f) NamedFunc(f, #f)

NamedFunc hashFunctions[] = {
    // From the 2015 paper:
    NAMED(&hashVHASH64), NAMED(&CLHASH), NAMED(&hashCity), NAMED(&hashSipHash),
    NAMED(&GHASH64bit),
    // Horner methods:
    NAMED(&hornerHash), NAMED(&unrolledHorner4), NAMED(&twiceHorner32),
    NAMED(&iterateCL11),
    // Tree hashing:
    NAMED(&treeCL9), NAMED(&simple_treehash), NAMED(&recursive_treehash),
    NAMED(&binary_treehash), NAMED(&boosted_treehash<1>),
    NAMED(&boosted_treehash<2>), NAMED(&boosted_treehash<3>),
    NAMED(&boosted_treehash<4>), NAMED(&boosted_treehash<5>),
    NAMED(&boosted_treehash<6>), NAMED(&boosted_treehash<7>),
    NAMED(&simple_cl_treehash), NAMED(&generic_simple_treehash<MultiplyShift>),
    NAMED(&generic_simple_treehash<NH>), NAMED(&generic_simple_treehash<CLNH>),
    NAMED((&generic_simple_treehash<Wide<MultiplyShift, 15> >)),
    NAMED((&generic_simple_treehash<Wide<NH, 4> >)),
    NAMED((&generic_simple_treehash<Wide<CLNH, 4> >)),
    NAMED((&generic_simple_treehash<Wide<CLNHx2, 4> >)),
};

const int HowManyFunctions64 =
    sizeof(hashFunctions) / sizeof(hashFunctions[0]);

int main(int c, char ** arg) {
    (void) (c);
    (void) (arg);
    uint64_t which_algos = ~0;
    assert(HowManyFunctions64 <= 64);
    if (c > 1) {
      if (1 != sscanf(arg[1], "%" SCNu64, &which_algos)) {
        return 1;
      }
    }
    int lengthStart = 1, lengthEnd = 2048; // inclusive
    if (c > 2)
        lengthStart = atoi(arg[2]);
    if (c > 3)
        lengthEnd = atoi(arg[3]);

    int i, j;
    int length;
    int SHORTTRIALS;
    struct timeval start, finish;
    uint64_t randbuffer[150] __attribute__ ((aligned (16)));// 150 should be plenty
    uint32_t sumToFoolCompiler = 0;
    uint64_t * intstring;
    // We need 32 bytes of alignment for working with __m256i's
    if (posix_memalign((void **)(&intstring), 32, sizeof(uint64_t)*lengthEnd)) {
      cerr << "Failed to allocate " << lengthEnd << " words." << endl;
      return 1;
    }
    for (i = 0; i < 150; ++i) {
        randbuffer[i] = rand() | ((uint64_t)(rand()) << 32);
    }
    for (i = 0; i < lengthEnd; ++i) {
        intstring[i] = rand() | ((uint64_t)(rand()) << 32);
    }
    printf("#Reporting the number of cycles per byte.\n");
    printf("#First number is input length in  8-byte words.\n");
    printf("0 ");
    for (i = 0; i < HowManyFunctions64; ++i) {
        if (which_algos & (0x1ull << i))
          cout << '"' << hashFunctions[i].name << "\" ";
    }
    printf("\n");
    fflush(stdout);
    for (length = lengthStart; length <= lengthEnd; length += 1) {
        SHORTTRIALS = 8000000 / length;
        printf("%8d \t\t", length);

        for (i = 0; i < HowManyFunctions64; ++i) {
            if (!(which_algos & (0x1ull << i)))
                continue;  // skip unselected algos
            const hashFunction64 thisfunc64 = hashFunctions[i].f;
            sumToFoolCompiler += thisfunc64(randbuffer, intstring, length); // we do not count the first one
            gettimeofday(&start, 0);
            ticks lowest = ~(ticks)0;
            for (j = 0; j < SHORTTRIALS; ++j) {
                const ticks bef = startRDTSC();
                sumToFoolCompiler += thisfunc64(randbuffer, intstring, length);
                const ticks aft = stopRDTSCP();
                const ticks diff = aft-bef;
                lowest = (lowest < diff) ? lowest : diff;
            }
            gettimeofday(&finish, 0);
            printf(" %.3f ", lowest * 1.0 / (8.0 * length));
            fflush(stdout);
        }
        printf("\n");
    }
    free(intstring);
    printf("# ignore this #%d\n", sumToFoolCompiler);

}

<|endoftext|>


<commit_before>#include <boost/pointer_cast.hpp>
#include "messageStream.h"

using namespace watcher;
using namespace watcher::event;
using namespace std;

INIT_LOGGER(MessageStream, "MessageStream");

MessageStream::MessageStream(const string &serverName_, const Timestamp &startTime_, const float streamRate_) :
    messageStreamFilters(),
    streamRate(streamRate_),
    streamStartTime(startTime_),
    connection(new Client(serverName_, shared_from_this()))  // GTL - there has got to be a better way to do this.
{
    TRACE_ENTER();
    TRACE_EXIT();
}

// virtual
MessageStream::~MessageStream()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

bool MessageStream::setStreamTimeStart(const Timestamp &startTime)
{
    TRACE_ENTER()
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::setStreamRate(const float &messageStreamRate)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::getNextMessage(MessagePtr newMessage)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::isStreamReadable() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::addMessageFilter(const MessageStreamFilter &filter)
{
    TRACE_ENTER();

    assert(0);  // filters are not supported yet.

    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::getMessageTimeRange(Timestamp &startTime, Timestamp endTime)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}

//virtual
std::ostream &MessageStream::toStream(std::ostream &out) const
{
    TRACE_ENTER();
    out << "MessageStream output operator not yet implemented - this space intensionally left blank";
    TRACE_EXIT();
    return out;
}
bool MessageStream::startStream()
{
    TRACE_ENTER();
    // startWatcherMessagePtr mess(new startWatcherMessage);
    // bool retVal=connection.sendMessage(mess);
    // TRACE_EXIT_RET((retVal==true?"true":"false"));
    // return retVal;
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::stopStream()
{
    TRACE_ENTER();
    // stopWatcherMessagePtr mess(new stopWatcherMessage);
    // bool retVal=connection.sendMessage(mess);
    // TRACE_EXIT_RET((retVal==true?"true":"false"));
    // return retVal;
    TRACE_EXIT_RET("true");
    return true;
}

//virtual
bool MessageStream::messageArrived(MessagePtr message)
{
    TRACE_ENTER();
    TRACE_EXIT();
}

std::ostream &operator<<(std::ostream &out, const MessageStream &messStream)
{
    TRACE_ENTER();
    TRACE_EXIT();
    return out;
}
<commit_msg>return value from skel function to stop warning.<commit_after>#include <boost/pointer_cast.hpp>
#include "messageStream.h"

using namespace watcher;
using namespace watcher::event;
using namespace std;

INIT_LOGGER(MessageStream, "MessageStream");

MessageStream::MessageStream(const string &serverName_, const Timestamp &startTime_, const float streamRate_) :
    messageStreamFilters(),
    streamRate(streamRate_),
    streamStartTime(startTime_),
    connection(new Client(serverName_, shared_from_this()))  // GTL - there has got to be a better way to do this.
{
    TRACE_ENTER();
    TRACE_EXIT();
}

// virtual
MessageStream::~MessageStream()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

bool MessageStream::setStreamTimeStart(const Timestamp &startTime)
{
    TRACE_ENTER()
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::setStreamRate(const float &messageStreamRate)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::getNextMessage(MessagePtr newMessage)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::isStreamReadable() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::addMessageFilter(const MessageStreamFilter &filter)
{
    TRACE_ENTER();

    assert(0);  // filters are not supported yet.

    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::getMessageTimeRange(Timestamp &startTime, Timestamp endTime)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("true");
    return true;
}

//virtual
std::ostream &MessageStream::toStream(std::ostream &out) const
{
    TRACE_ENTER();
    out << "MessageStream output operator not yet implemented - this space intensionally left blank";
    TRACE_EXIT();
    return out;
}
bool MessageStream::startStream()
{
    TRACE_ENTER();
    // startWatcherMessagePtr mess(new startWatcherMessage);
    // bool retVal=connection.sendMessage(mess);
    // TRACE_EXIT_RET((retVal==true?"true":"false"));
    // return retVal;
    TRACE_EXIT_RET("true");
    return true;
}
bool MessageStream::stopStream()
{
    TRACE_ENTER();
    // stopWatcherMessagePtr mess(new stopWatcherMessage);
    // bool retVal=connection.sendMessage(mess);
    // TRACE_EXIT_RET((retVal==true?"true":"false"));
    // return retVal;
    TRACE_EXIT_RET("true");
    return true;
}

//virtual
bool MessageStream::messageArrived(MessagePtr message)
{
    TRACE_ENTER();
    TRACE_EXIT_RET("false");
    return false;
}

std::ostream &operator<<(std::ostream &out, const MessageStream &messStream)
{
    TRACE_ENTER();
    TRACE_EXIT();
    return out;
}
<|endoftext|>