<commit_before>//===- ScalarReplAggregates.cpp - Scalar Replacement of Aggregates --------===//
//
// This transformation implements the well known scalar replacement of
// aggregates transformation.  This xform breaks up alloca instructions of
// aggregate type (structure or array) into individual alloca instructions for
// each member (if possible).
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/iMemory.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "Support/StringExtras.h"
#include "Support/Statistic.h"

namespace {
  Statistic<> NumReplaced("scalarrepl", "Number of alloca's broken up");

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

  private:
    AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base);
  };

  RegisterOpt<SROA> X("scalarrepl", "Scalar Replacement of Aggregates");
}

Pass *createScalarReplAggregatesPass() { return new SROA(); }

// runOnFunction - This algorithm is a simple worklist driven algorithm, which
// runs on all of the malloc/alloca instructions in the function, removing them
// if they are only used by getelementptr instructions.
//
bool SROA::runOnFunction(Function &F) {
  std::vector<AllocationInst*> WorkList;

  // Scan the entry basic block, adding any alloca's and mallocs to the worklist
  BasicBlock &BB = F.getEntryNode();
  for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
    if (AllocationInst *A = dyn_cast<AllocationInst>(I))
      WorkList.push_back(A);

  // Process the worklist
  bool Changed = false;
  while (!WorkList.empty()) {
    AllocationInst *AI = WorkList.back();
    WorkList.pop_back();

    // We cannot transform the allocation instruction if it is an array
    // allocation (allocations OF arrays are ok though), and an allocation of a
    // scalar value cannot be decomposed at all.
    //
    if (AI->isArrayAllocation() ||
        (!isa<StructType>(AI->getAllocatedType()) &&
         !isa<ArrayType>(AI->getAllocatedType()))) continue;

    const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType());

    // Loop over the use list of the alloca.  We can only transform it if there
    // are only getelementptr instructions (with a zero first index) and free
    // instructions.
    //
    bool CannotTransform = false;
    for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
         I != E; ++I) {
      Instruction *User = cast<Instruction>(*I);
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
        // The GEP is safe to transform if it is of the form GEP <ptr>, 0, <cst>
        if (GEPI->getNumOperands() <= 2 ||
            GEPI->getOperand(1) != Constant::getNullValue(Type::LongTy) ||
            !isa<Constant>(GEPI->getOperand(2)) ||
            isa<ConstantExpr>(GEPI->getOperand(2))) {
          DEBUG(std::cerr << "Cannot transform: " << *AI << "  due to user: "
                          << User);
          CannotTransform = true;
          break;
        }

        // If this is an array access, check to make sure that index falls
        // within the array.  If not, something funny is going on, so we won't
        // do the optimization.
        if (AT && cast<ConstantSInt>(GEPI->getOperand(2))->getValue() >=
            AT->getNumElements()) {
          DEBUG(std::cerr << "Cannot transform: " << *AI << "  due to user: "
                          << User);
          CannotTransform = true;
          break;
        }

      } else {
        DEBUG(std::cerr << "Cannot transform: " << *AI << "  due to user: "
                        << User);
        CannotTransform = true;
        break;
      }
    }

    if (CannotTransform) continue;

    DEBUG(std::cerr << "Found inst to xform: " << *AI);
    Changed = true;

    std::vector<AllocaInst*> ElementAllocas;
    if (const StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
      ElementAllocas.reserve(ST->getNumContainedTypes());
      for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
        AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0,
                                        AI->getName() + "." + utostr(i), AI);
        ElementAllocas.push_back(NA);
        WorkList.push_back(NA);  // Add to worklist for recursive processing
      }
    } else {
      ElementAllocas.reserve(AT->getNumElements());
      const Type *ElTy = AT->getElementType();
      for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
        AllocaInst *NA = new AllocaInst(ElTy, 0,
                                        AI->getName() + "." + utostr(i), AI);
        ElementAllocas.push_back(NA);
        WorkList.push_back(NA);  // Add to worklist for recursive processing
      }
    }

    // Now that we have created the alloca instructions that we want to use,
    // expand the getelementptr instructions to use them.
    //
    for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
         I != E; ++I) {
      Instruction *User = cast<Instruction>(*I);
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
        // We now know that the GEP is of the form: GEP <ptr>, 0, <cst>
        uint64_t Idx;
        if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(GEPI->getOperand(2)))
          Idx = CSI->getValue();
        else
          Idx = cast<ConstantUInt>(GEPI->getOperand(2))->getValue();

        assert(Idx < ElementAllocas.size() && "Index out of range?");
        AllocaInst *AllocaToUse = ElementAllocas[Idx];

        Value *RepValue;
        if (GEPI->getNumOperands() == 3) {
          // Do not insert a new getelementptr instruction with zero indices,
          // only to have it optimized out later.
          RepValue = AllocaToUse;
        } else {
          // We are indexing deeply into the structure, so we still need a
          // getelement ptr instruction to finish the indexing.  This may be
          // expanded itself once the worklist is rerun.
          //
          std::string OldName = GEPI->getName();  // Steal the old name...
          GEPI->setName("");
          RepValue =
            new GetElementPtrInst(AllocaToUse,
                                  std::vector<Value*>(GEPI->op_begin()+3,
                                                      GEPI->op_end()),
                                  OldName, GEPI);
        }

        // Move all of the users over to the new GEP.
        GEPI->replaceAllUsesWith(RepValue);
        // Delete the old GEP
        GEPI->getParent()->getInstList().erase(GEPI);
      } else {
        assert(0 && "Unexpected instruction type!");
      }
    }

    // Finally, delete the Alloca instruction
    AI->getParent()->getInstList().erase(AI);
    NumReplaced++;
  }

  return Changed;
}
<commit_msg>Fix bug: ScalarRepl/2003-05-29-ArrayFail.ll<commit_after>//===- ScalarReplAggregates.cpp - Scalar Replacement of Aggregates --------===//
//
// This transformation implements the well known scalar replacement of
// aggregates transformation.  This xform breaks up alloca instructions of
// aggregate type (structure or array) into individual alloca instructions for
// each member (if possible).
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/iMemory.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "Support/StringExtras.h"
#include "Support/Statistic.h"

namespace {
  Statistic<> NumReplaced("scalarrepl", "Number of alloca's broken up");

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

  private:
    bool isSafeArrayElementUse(Value *Ptr);
    bool isSafeUseOfAllocation(Instruction *User);
    bool isSafeStructAllocaToPromote(AllocationInst *AI);
    bool isSafeArrayAllocaToPromote(AllocationInst *AI);
    AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base);
  };

  RegisterOpt<SROA> X("scalarrepl", "Scalar Replacement of Aggregates");
}

Pass *createScalarReplAggregatesPass() { return new SROA(); }

// runOnFunction - This algorithm is a simple worklist driven algorithm, which
// runs on all of the malloc/alloca instructions in the function, removing them
// if they are only used by getelementptr instructions.
//
bool SROA::runOnFunction(Function &F) {
  std::vector<AllocationInst*> WorkList;

  // Scan the entry basic block, adding any alloca's and mallocs to the worklist
  BasicBlock &BB = F.getEntryNode();
  for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
    if (AllocationInst *A = dyn_cast<AllocationInst>(I))
      WorkList.push_back(A);

  // Process the worklist
  bool Changed = false;
  while (!WorkList.empty()) {
    AllocationInst *AI = WorkList.back();
    WorkList.pop_back();

    // We cannot transform the allocation instruction if it is an array
    // allocation (allocations OF arrays are ok though), and an allocation of a
    // scalar value cannot be decomposed at all.
    //
    if (AI->isArrayAllocation() ||
        (!isa<StructType>(AI->getAllocatedType()) &&
         !isa<ArrayType>(AI->getAllocatedType()))) continue;

    // Check that all of the users of the allocation are capable of being
    // transformed.
    if (isa<StructType>(AI->getAllocatedType())) {
      if (!isSafeStructAllocaToPromote(AI))
        continue;
    } else if (!isSafeArrayAllocaToPromote(AI))
      continue;

    DEBUG(std::cerr << "Found inst to xform: " << *AI);
    Changed = true;

    std::vector<AllocaInst*> ElementAllocas;
    if (const StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
      ElementAllocas.reserve(ST->getNumContainedTypes());
      for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
        AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0,
                                        AI->getName() + "." + utostr(i), AI);
        ElementAllocas.push_back(NA);
        WorkList.push_back(NA);  // Add to worklist for recursive processing
      }
    } else {
      const ArrayType *AT = cast<ArrayType>(AI->getAllocatedType());
      ElementAllocas.reserve(AT->getNumElements());
      const Type *ElTy = AT->getElementType();
      for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
        AllocaInst *NA = new AllocaInst(ElTy, 0,
                                        AI->getName() + "." + utostr(i), AI);
        ElementAllocas.push_back(NA);
        WorkList.push_back(NA);  // Add to worklist for recursive processing
      }
    }

    // Now that we have created the alloca instructions that we want to use,
    // expand the getelementptr instructions to use them.
    //
    for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
         I != E; ++I) {
      Instruction *User = cast<Instruction>(*I);
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
        // We now know that the GEP is of the form: GEP <ptr>, 0, <cst>
        uint64_t Idx;
        if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(GEPI->getOperand(2)))
          Idx = CSI->getValue();
        else
          Idx = cast<ConstantUInt>(GEPI->getOperand(2))->getValue();

        assert(Idx < ElementAllocas.size() && "Index out of range?");
        AllocaInst *AllocaToUse = ElementAllocas[Idx];

        Value *RepValue;
        if (GEPI->getNumOperands() == 3) {
          // Do not insert a new getelementptr instruction with zero indices,
          // only to have it optimized out later.
          RepValue = AllocaToUse;
        } else {
          // We are indexing deeply into the structure, so we still need a
          // getelement ptr instruction to finish the indexing.  This may be
          // expanded itself once the worklist is rerun.
          //
          std::string OldName = GEPI->getName();  // Steal the old name...
          GEPI->setName("");
          RepValue =
            new GetElementPtrInst(AllocaToUse,
                                  std::vector<Value*>(GEPI->op_begin()+3,
                                                      GEPI->op_end()),
                                  OldName, GEPI);
        }

        // Move all of the users over to the new GEP.
        GEPI->replaceAllUsesWith(RepValue);
        // Delete the old GEP
        GEPI->getParent()->getInstList().erase(GEPI);
      } else {
        assert(0 && "Unexpected instruction type!");
      }
    }

    // Finally, delete the Alloca instruction
    AI->getParent()->getInstList().erase(AI);
    NumReplaced++;
  }

  return Changed;
}

/// isSafeUseOfAllocation - Check to see if this user is an allowed use for an
/// aggregate allocation.
///
bool SROA::isSafeUseOfAllocation(Instruction *User) {
  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
    // The GEP is safe to transform if it is of the form GEP <ptr>, 0, <cst>
    if (GEPI->getNumOperands() <= 2 ||
        GEPI->getOperand(1) != Constant::getNullValue(Type::LongTy) ||
        !isa<Constant>(GEPI->getOperand(2)) ||
        isa<ConstantExpr>(GEPI->getOperand(2)))
      return false;
  } else {
    return false;
  }
  return true;
}

/// isSafeArrayElementUse - Check to see if this use is an allowed use for a
/// getelementptr instruction of an array aggregate allocation.
///
bool SROA::isSafeArrayElementUse(Value *Ptr) {
  for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
       I != E; ++I) {
    Instruction *User = cast<Instruction>(*I);
    switch (User->getOpcode()) {
    case Instruction::Load:  return true;
    case Instruction::Store: return User->getOperand(0) != Ptr;
    case Instruction::GetElementPtr: {
      GetElementPtrInst *GEP = cast<GetElementPtrInst>(User);
      if (GEP->getNumOperands() > 1) {
        if (!isa<Constant>(GEP->getOperand(1)) ||
            !cast<Constant>(GEP->getOperand(1))->isNullValue())
          return false;  // Using pointer arithmetic to navigate the array...

        // Check to see if there are any structure indexes involved in this GEP.
        // If so, then we can safely break the array up until at least the
        // structure.
        for (unsigned i = 2, e = GEP->getNumOperands(); i != e; ++i)
          if (GEP->getOperand(i)->getType()->isUnsigned())
            break;
      }
      return isSafeArrayElementUse(GEP);
    }
    default:
      DEBUG(std::cerr << "  Transformation preventing inst: " << *User);
      return false;
    }
  }
  return true;  // All users look ok :)
}

/// isSafeStructAllocaToPromote - Check to see if the specified allocation of a
/// structure can be broken down into elements.
///
bool SROA::isSafeStructAllocaToPromote(AllocationInst *AI) {
  // Loop over the use list of the alloca.  We can only transform it if all of
  // the users are safe to transform.
  //
  for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
       I != E; ++I)
    if (!isSafeUseOfAllocation(cast<Instruction>(*I))) {
      DEBUG(std::cerr << "Cannot transform: " << *AI << "  due to user: "
                      << *I);
      return false;
    }
  return true;
}

/// isSafeArrayAllocaToPromote - Check to see if the specified allocation of a
/// structure can be broken down into elements.
///
bool SROA::isSafeArrayAllocaToPromote(AllocationInst *AI) {
  const ArrayType *AT = cast<ArrayType>(AI->getAllocatedType());
  int64_t NumElements = AT->getNumElements();

  // Loop over the use list of the alloca.  We can only transform it if all of
  // the users are safe to transform.  Array allocas have extra constraints to
  // meet though.
  //
  for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
       I != E; ++I) {
    Instruction *User = cast<Instruction>(*I);
    if (!isSafeUseOfAllocation(User)) {
      DEBUG(std::cerr << "Cannot transform: " << *AI << "  due to user: "
                      << User);
      return false;
    }

    // Check to make sure that getelementptr follow the extra rules for arrays:
    if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
      // Check to make sure that index falls within the array.  If not,
      // something funny is going on, so we won't do the optimization.
      //
      if (cast<ConstantSInt>(GEPI->getOperand(2))->getValue() >= NumElements)
        return false;

      // Check to make sure that the only thing that uses the resultant pointer
      // is safe for an array access.  For example, code that looks like:
      //   P = &A[0];  P = P + 1
      // is legal, and should prevent promotion.
      //
      if (!isSafeArrayElementUse(GEPI)) {
        DEBUG(std::cerr << "Cannot transform: " << *AI
                        << "  due to uses of user: " << *GEPI);
        return false;
      }
    }
  }
  return true;
}

<|endoftext|>


<commit_before>// Copyright © 2017-2018 Dmitriy Khaustov
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.07.02

// Application.hpp

#pragma once

#include "../utils/Shareable.hpp"
#include "../configs/Setting.hpp"
#include <string>

class Application : public Shareable<Application>
{
protected:
	std::string _type;
	std::string _appId;
	bool _isProduction;

public:
	Application() = delete;
	Application(const Application&) = delete;
    Application& operator=(Application const&) = delete;
	Application(Application&&) noexcept = delete;
	Application& operator=(Application&&) noexcept = delete;

	explicit Application(const Setting& setting);
	~Application() override = default;

	const std::string& type() const
	{
		return _type;
	}

	const std::string& appId() const
	{
		return _appId;
	}

	bool isProduction() const
	{
		return _isProduction;
	}
};

#include "ApplicationFactory.hpp"

#define REGISTER_APPLICATION(Type,Class) const Dummy Class::__dummy = \
    ApplicationFactory::reg(                                                                    \
        #Type,                                                                                \
        [](const Setting& setting){                                                             \
            return std::shared_ptr<::Application>(new Class(setting));                          \
        }                                                                                \
    );

#define DECLARE_APPLICATION(Class) \
public:                                                                                \
	Class() = delete;                                                                           \
	Class(const Class&) = delete;                                                               \
    Class& operator=(Class const&) = delete;                                                    \
	Class(Class&&) noexcept = delete;                                                           \
	Class& operator=(Class&&) noexcept = delete;                                                \
    ~Class() override = default;                                                                \
                                                                                \
private:                                                                                \
    Class(const Setting& setting);                                                              \
                                                                                \
private:                                                                                \
    static const Dummy __dummy;
<commit_msg>Add type for id of Applications'<commit_after>// Copyright © 2017-2018 Dmitriy Khaustov
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.07.02

// Application.hpp

#pragma once

#include "../utils/Shareable.hpp"
#include "../configs/Setting.hpp"
#include <string>

class Application : public Shareable<Application>
{
public:
	typedef std::string Type;
	typedef std::string Id;

protected:
	Type _type;
	Id _appId;
	bool _isProduction;

public:
	Application() = delete;
	Application(const Application&) = delete;
    Application& operator=(Application const&) = delete;
	Application(Application&&) noexcept = delete;
	Application& operator=(Application&&) noexcept = delete;

	explicit Application(const Setting& setting);
	~Application() override = default;

	const Type& type() const
	{
		return _type;
	}

	const Id& appId() const
	{
		return _appId;
	}

	bool isProduction() const
	{
		return _isProduction;
	}
};

#include "ApplicationFactory.hpp"

#define REGISTER_APPLICATION(Type,Class) const Dummy Class::__dummy = \
    ApplicationFactory::reg(                                                                    \
        #Type,                                                                                \
        [](const Setting& setting){                                                             \
            return std::shared_ptr<::Application>(new Class(setting));                          \
        }                                                                                \
    );

#define DECLARE_APPLICATION(Class) \
public:                                                                                \
	Class() = delete;                                                                           \
	Class(const Class&) = delete;                                                               \
    Class& operator=(Class const&) = delete;                                                    \
	Class(Class&&) noexcept = delete;                                                           \
	Class& operator=(Class&&) noexcept = delete;                                                \
    ~Class() override = default;                                                                \
                                                                                \
private:                                                                                \
    Class(const Setting& setting);                                                              \
                                                                                \
private:                                                                                \
    static const Dummy __dummy;
<|endoftext|>


<commit_before>#include "pch.h"
#include "MyPropertyPage.h"

#include "DspMatrix.h"

namespace SaneAudioRenderer
{
    namespace
    {
        void Write(std::vector<char>& out, void* src, size_t size)
        {
            assert(src);
            assert(size > 0);
            out.insert(out.end(), size, 0);
            memcpy(&out[out.size() - size], src, size);
        }

        template <typename T>
        void Write(std::vector<char>& out, T t)
        {
            Write(out, &t, sizeof(T));
        }

        void WriteString(std::vector<char>& out, const std::wstring& str)
        {
            Write(out, (void*)str.c_str(), sizeof(wchar_t) * (str.length() + 1));
        }

        void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize)
        {
            assert(out.empty());

            Write<DWORD>(out, DS_SETFONT | DS_FIXEDSYS | WS_CHILD);
            Write<DWORD>(out, 0);
            Write<WORD>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<WORD>(out, 0);
            Write<WORD>(out, 0);
            WriteString(out, L"");
            Write<WORD>(out, fontSize);
            WriteString(out, font);
        }

        void WriteDialogItem(std::vector<char>& out, DWORD style, DWORD control, short x, short y, short w, short h,
                             const std::wstring& text)
        {
            assert(!out.empty());

            if (out.size() % 4)
                out.insert(out.end(), out.size() % 4, 0);

            Write<DWORD>(out, style | WS_CHILD | WS_VISIBLE);
            Write<DWORD>(out, 0);
            Write<short>(out, x);
            Write<short>(out, y);
            Write<short>(out, w);
            Write<short>(out, h);
            Write<WORD>(out, 0);
            Write<DWORD>(out, control);
            WriteString(out, text);
            Write<WORD>(out, 0);

            *(WORD*)(&out[8]) += 1;
        }

        std::wstring GetFormatString(const WAVEFORMATEX& format)
        {
            DspFormat dspFormat = DspFormatFromWaveFormat(format);

            const WAVEFORMATEXTENSIBLE* pFormatExt =
                (format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) ?
                    reinterpret_cast<const WAVEFORMATEXTENSIBLE*>(&format) : nullptr;

            bool pcm24in32 = (dspFormat == DspFormat::Pcm32 &&
                              pFormatExt && pFormatExt->Samples.wValidBitsPerSample == 24);

            switch (dspFormat)
            {
                case DspFormat::Pcm8:
                    return L"PCM-8";

                case DspFormat::Pcm16:
                    return L"PCM-16";

                case DspFormat::Pcm24:
                    return L"PCM-24";

                case DspFormat::Pcm32:
                    return pcm24in32 ? L"PCM-24 (Padded)" : L"PCM-32";

                case DspFormat::Float:
                    return L"Float";

                case DspFormat::Double:
                    return L"Double";
            }

            assert(dspFormat == DspFormat::Unknown);

            if (format.wFormatTag == WAVE_FORMAT_DOLBY_AC3_SPDIF)
                return L"AC3/DTS";

            if (pFormatExt)
            {
                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD)
                    return L"DTS-HD";

                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
                    return L"TrueHD";

                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_WMA_PRO)
                    return L"WMA Pro";
            }

            return L"Unknown";
        }
    }

    MyPropertyPage::MyPropertyPage(SharedWaveFormat inputFormat, AudioDevice const* pDevice,
                                   std::vector<std::wstring> processors)
        : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
    {
        std::wstring adapterField = (pDevice && pDevice->GetAdapterName()) ? *pDevice->GetAdapterName() : L"-";

        std::wstring endpointField = (pDevice && pDevice->GetEndpointName()) ? *pDevice->GetEndpointName() : L"-";

        std::wstring exclusiveField = (pDevice ? (pDevice->IsExclusive() ? L"Yes" : L"No") : L"-");

        std::wstring bufferField = (pDevice ? std::to_wstring(pDevice->GetBufferDuration()) + L"ms" : L"-");

        std::wstring bitstreamingField = (inputFormat ? (DspFormatFromWaveFormat(*inputFormat) ==
                                                         DspFormat::Unknown ? L"Yes" : L"No") : L"-");

        std::wstring externalClockField = L"N/A";

        std::wstring channelsInputField = (inputFormat ? std::to_wstring(inputFormat->nChannels) +
                                              L" (" + GetHexString(DspMatrix::GetChannelMask(*inputFormat)) + L")" : L"-");
        std::wstring channelsDeviceField = (pDevice ? std::to_wstring(pDevice->GetWaveFormat()->nChannels) +
                                              L" (" + GetHexString(DspMatrix::GetChannelMask(*pDevice->GetWaveFormat())) + L")" : L"-");
        std::wstring channelsField = (channelsInputField == channelsDeviceField) ?
                                         channelsInputField : channelsInputField + L" -> " + channelsDeviceField;

        std::wstring formatInputField = (inputFormat ? GetFormatString(*inputFormat) : L"-");
        std::wstring formatDeviceField = (pDevice ? GetFormatString(*pDevice->GetWaveFormat()) : L"-");
        std::wstring formatField = (formatInputField == formatDeviceField) ?
                                       formatInputField : formatInputField + L" -> " + formatDeviceField;

        std::wstring rateInputField = (inputFormat ? std::to_wstring(inputFormat->nSamplesPerSec) : L"-");
        std::wstring rateDeviceField = (pDevice ? std::to_wstring(pDevice->GetWaveFormat()->nSamplesPerSec) : L"-");
        std::wstring rateField = (rateInputField == rateDeviceField) ?
                                      rateInputField : rateInputField + L" -> " + rateDeviceField;

        std::wstring processorsField;
        for (const auto& s : processors)
        {
            if (!processorsField.empty())
                processorsField += L", ";

            processorsField += s;
        }
        if (processorsField.empty())
            processorsField = L"-";

        WriteDialogHeader(m_dialogData, L"MS Shell Dlg", 8);
        WriteDialogItem(m_dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 200, 150, L"Renderer Status");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20,  60,  8, L"Adapter:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 20,  120, 8, adapterField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32,  60,  8, L"Endpoint:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 32,  120, 8, endpointField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44,  60,  8, L"Exclusive:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 44,  120, 8, exclusiveField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56,  60,  8, L"Buffer:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 56,  120, 8, bufferField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68,  60,  8, L"Bitstreaming:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 68,  120, 8, bitstreamingField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80,  60,  8, L"External Clock:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 80,  120, 8, externalClockField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92,  60,  8, L"Format:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 92,  120, 8, formatField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60,  8, L"Channels:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 104, 120, 8, channelsField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60,  8, L"Rate:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 116, 120, 8, rateField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60,  8, L"Processors:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 128, 120, 24, processorsField);
    }

    STDMETHODIMP MyPropertyPage::NonDelegatingQueryInterface(REFIID riid, void** ppv)
    {
        return (riid == __uuidof(IPropertyPage)) ?
                   GetInterface(static_cast<IPropertyPage*>(this), ppv) :
                   CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }

    STDMETHODIMP MyPropertyPage::SetPageSite(IPropertyPageSite* pPageSite)
    {
        if (!m_pageSite && !pPageSite)
            return E_UNEXPECTED;

        m_pageSite = nullptr;
        CheckPointer(pPageSite, S_OK);

        return pPageSite->QueryInterface(IID_PPV_ARGS(&m_pageSite));
    }

    STDMETHODIMP MyPropertyPage::Activate(HWND hParent, LPCRECT pRect, BOOL bModal)
    {
        CheckPointer(pRect, E_POINTER);

        m_hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), hParent, nullptr);

        return (m_hWindow != NULL) ? S_OK : E_UNEXPECTED;
    }

    STDMETHODIMP MyPropertyPage::Deactivate()
    {
        DestroyWindow(m_hWindow);
        m_hWindow = NULL;
        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::GetPageInfo(PROPPAGEINFO* pPageInfo)
    {
        CheckPointer(pPageInfo, E_POINTER);

        pPageInfo->cb = sizeof(PROPPAGEINFO);

        const wchar_t title[] = L"Status";
        pPageInfo->pszTitle = (LPOLESTR)CoTaskMemAlloc(sizeof(title));
        CheckPointer(pPageInfo->pszTitle, E_OUTOFMEMORY);
        memcpy(pPageInfo->pszTitle, title, sizeof(title));

        pPageInfo->size = {0, 0};
        pPageInfo->pszDocString = nullptr;
        pPageInfo->pszHelpFile = nullptr;
        pPageInfo->dwHelpContext = 0;

        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::Show(UINT cmdShow)
    {
        ShowWindow(m_hWindow, cmdShow);
        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::Move(LPCRECT pRect)
    {
        MoveWindow(m_hWindow, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, TRUE);
        return S_OK;
    }
}
<commit_msg>Add "Rate Matching" field to MyPropertyPage<commit_after>#include "pch.h"
#include "MyPropertyPage.h"

#include "DspMatrix.h"

namespace SaneAudioRenderer
{
    namespace
    {
        void Write(std::vector<char>& out, void* src, size_t size)
        {
            assert(src);
            assert(size > 0);
            out.insert(out.end(), size, 0);
            memcpy(&out[out.size() - size], src, size);
        }

        template <typename T>
        void Write(std::vector<char>& out, T t)
        {
            Write(out, &t, sizeof(T));
        }

        void WriteString(std::vector<char>& out, const std::wstring& str)
        {
            Write(out, (void*)str.c_str(), sizeof(wchar_t) * (str.length() + 1));
        }

        void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize)
        {
            assert(out.empty());

            Write<DWORD>(out, DS_SETFONT | DS_FIXEDSYS | WS_CHILD);
            Write<DWORD>(out, 0);
            Write<WORD>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<short>(out, 0);
            Write<WORD>(out, 0);
            Write<WORD>(out, 0);
            WriteString(out, L"");
            Write<WORD>(out, fontSize);
            WriteString(out, font);
        }

        void WriteDialogItem(std::vector<char>& out, DWORD style, DWORD control, short x, short y, short w, short h,
                             const std::wstring& text)
        {
            assert(!out.empty());

            if (out.size() % 4)
                out.insert(out.end(), out.size() % 4, 0);

            Write<DWORD>(out, style | WS_CHILD | WS_VISIBLE);
            Write<DWORD>(out, 0);
            Write<short>(out, x);
            Write<short>(out, y);
            Write<short>(out, w);
            Write<short>(out, h);
            Write<WORD>(out, 0);
            Write<DWORD>(out, control);
            WriteString(out, text);
            Write<WORD>(out, 0);

            *(WORD*)(&out[8]) += 1;
        }

        std::wstring GetFormatString(const WAVEFORMATEX& format)
        {
            DspFormat dspFormat = DspFormatFromWaveFormat(format);

            const WAVEFORMATEXTENSIBLE* pFormatExt =
                (format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) ?
                    reinterpret_cast<const WAVEFORMATEXTENSIBLE*>(&format) : nullptr;

            bool pcm24in32 = (dspFormat == DspFormat::Pcm32 &&
                              pFormatExt && pFormatExt->Samples.wValidBitsPerSample == 24);

            switch (dspFormat)
            {
                case DspFormat::Pcm8:
                    return L"PCM-8";

                case DspFormat::Pcm16:
                    return L"PCM-16";

                case DspFormat::Pcm24:
                    return L"PCM-24";

                case DspFormat::Pcm32:
                    return pcm24in32 ? L"PCM-24 (Padded)" : L"PCM-32";

                case DspFormat::Float:
                    return L"Float";

                case DspFormat::Double:
                    return L"Double";
            }

            assert(dspFormat == DspFormat::Unknown);

            if (format.wFormatTag == WAVE_FORMAT_DOLBY_AC3_SPDIF)
                return L"AC3/DTS";

            if (pFormatExt)
            {
                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD)
                    return L"DTS-HD";

                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
                    return L"TrueHD";

                if (pFormatExt->SubFormat == KSDATAFORMAT_SUBTYPE_IEC61937_WMA_PRO)
                    return L"WMA Pro";
            }

            return L"Unknown";
        }
    }

    MyPropertyPage::MyPropertyPage(SharedWaveFormat inputFormat, AudioDevice const* pDevice,
                                   std::vector<std::wstring> processors)
        : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
    {
        std::wstring adapterField = (pDevice && pDevice->GetAdapterName()) ? *pDevice->GetAdapterName() : L"-";

        std::wstring endpointField = (pDevice && pDevice->GetEndpointName()) ? *pDevice->GetEndpointName() : L"-";

        std::wstring exclusiveField = (pDevice ? (pDevice->IsExclusive() ? L"Yes" : L"No") : L"-");

        std::wstring bufferField = (pDevice ? std::to_wstring(pDevice->GetBufferDuration()) + L"ms" : L"-");

        std::wstring bitstreamingField = (inputFormat ? (DspFormatFromWaveFormat(*inputFormat) ==
                                                         DspFormat::Unknown ? L"Yes" : L"No") : L"-");

        std::wstring rateMatchingField = (pDevice && pDevice->IsLive()) ? L"Yes" : L"No";

        std::wstring channelsInputField = (inputFormat ? std::to_wstring(inputFormat->nChannels) +
                                              L" (" + GetHexString(DspMatrix::GetChannelMask(*inputFormat)) + L")" : L"-");
        std::wstring channelsDeviceField = (pDevice ? std::to_wstring(pDevice->GetWaveFormat()->nChannels) +
                                              L" (" + GetHexString(DspMatrix::GetChannelMask(*pDevice->GetWaveFormat())) + L")" : L"-");
        std::wstring channelsField = (channelsInputField == channelsDeviceField) ?
                                         channelsInputField : channelsInputField + L" -> " + channelsDeviceField;

        std::wstring formatInputField = (inputFormat ? GetFormatString(*inputFormat) : L"-");
        std::wstring formatDeviceField = (pDevice ? GetFormatString(*pDevice->GetWaveFormat()) : L"-");
        std::wstring formatField = (formatInputField == formatDeviceField) ?
                                       formatInputField : formatInputField + L" -> " + formatDeviceField;

        std::wstring rateInputField = (inputFormat ? std::to_wstring(inputFormat->nSamplesPerSec) : L"-");
        std::wstring rateDeviceField = (pDevice ? std::to_wstring(pDevice->GetWaveFormat()->nSamplesPerSec) : L"-");
        std::wstring rateField = (rateInputField == rateDeviceField) ?
                                      rateInputField : rateInputField + L" -> " + rateDeviceField;

        std::wstring processorsField;
        for (const auto& s : processors)
        {
            if (!processorsField.empty())
                processorsField += L", ";

            processorsField += s;
        }
        if (processorsField.empty())
            processorsField = L"-";

        WriteDialogHeader(m_dialogData, L"MS Shell Dlg", 8);
        WriteDialogItem(m_dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 200, 150, L"Renderer Status");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20,  60,  8, L"Adapter:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 20,  120, 8, adapterField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32,  60,  8, L"Endpoint:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 32,  120, 8, endpointField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44,  60,  8, L"Exclusive:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 44,  120, 8, exclusiveField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56,  60,  8, L"Buffer:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 56,  120, 8, bufferField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68,  60,  8, L"Bitstreaming:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 68,  120, 8, bitstreamingField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80,  60,  8, L"Rate Matching:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 80,  120, 8, rateMatchingField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92,  60,  8, L"Format:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 92,  120, 8, formatField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60,  8, L"Channels:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 104, 120, 8, channelsField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60,  8, L"Rate:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 116, 120, 8, rateField);
        WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60,  8, L"Processors:");
        WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT,  0x0082FFFF, 73, 128, 120, 24, processorsField);
    }

    STDMETHODIMP MyPropertyPage::NonDelegatingQueryInterface(REFIID riid, void** ppv)
    {
        return (riid == __uuidof(IPropertyPage)) ?
                   GetInterface(static_cast<IPropertyPage*>(this), ppv) :
                   CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }

    STDMETHODIMP MyPropertyPage::SetPageSite(IPropertyPageSite* pPageSite)
    {
        if (!m_pageSite && !pPageSite)
            return E_UNEXPECTED;

        m_pageSite = nullptr;
        CheckPointer(pPageSite, S_OK);

        return pPageSite->QueryInterface(IID_PPV_ARGS(&m_pageSite));
    }

    STDMETHODIMP MyPropertyPage::Activate(HWND hParent, LPCRECT pRect, BOOL bModal)
    {
        CheckPointer(pRect, E_POINTER);

        m_hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), hParent, nullptr);

        return (m_hWindow != NULL) ? S_OK : E_UNEXPECTED;
    }

    STDMETHODIMP MyPropertyPage::Deactivate()
    {
        DestroyWindow(m_hWindow);
        m_hWindow = NULL;
        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::GetPageInfo(PROPPAGEINFO* pPageInfo)
    {
        CheckPointer(pPageInfo, E_POINTER);

        pPageInfo->cb = sizeof(PROPPAGEINFO);

        const wchar_t title[] = L"Status";
        pPageInfo->pszTitle = (LPOLESTR)CoTaskMemAlloc(sizeof(title));
        CheckPointer(pPageInfo->pszTitle, E_OUTOFMEMORY);
        memcpy(pPageInfo->pszTitle, title, sizeof(title));

        pPageInfo->size = {0, 0};
        pPageInfo->pszDocString = nullptr;
        pPageInfo->pszHelpFile = nullptr;
        pPageInfo->dwHelpContext = 0;

        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::Show(UINT cmdShow)
    {
        ShowWindow(m_hWindow, cmdShow);
        return S_OK;
    }

    STDMETHODIMP MyPropertyPage::Move(LPCRECT pRect)
    {
        MoveWindow(m_hWindow, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, TRUE);
        return S_OK;
    }
}
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int main() {
    int x, y;
    cin >> x;
    if (x >= y) {cout << x;}
    else {cout << y;
    }
    return 0;
}<commit_msg>Delete task21.cpp<commit_after><|endoftext|>


<commit_before>//===- FxpMathConfig.cpp - Reference fixed point config -------------------===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
//
// This file defines a TargetConfiguration for reference fixed-point math
// quantization scheme based on the FxpMathOps (plus a small category of
// extension ops that can be added from other dialects).
//
//===----------------------------------------------------------------------===//

#include "mlir/Quantizer/Configurations/FxpMathConfig.h"

#include "mlir/Dialect/FxpMathOps/FxpMathOps.h"
#include "mlir/Dialect/QuantOps/QuantOps.h"
#include "mlir/Dialect/QuantOps/QuantTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Quantizer/Support/ConstraintAnalysisGraph.h"
#include "mlir/Quantizer/Support/Metadata.h"
#include "mlir/Quantizer/Support/Statistics.h"
#include "mlir/Quantizer/Support/UniformConstraints.h"
#include "mlir/StandardOps/Ops.h"

using namespace mlir;
using namespace mlir::quantizer;
using namespace mlir::fxpmath;
using namespace mlir::quant;
using namespace std::placeholders;

namespace {

struct FxpMathTargetConfigImpl : public FxpMathTargetConfig {
  FxpMathTargetConfigImpl(SolverContext &context)
      : FxpMathTargetConfig(context) {
    Builder b(&context.getMlirContext());
    IntegerType i8Type = b.getIntegerType(8);
    IntegerType i16Type = b.getIntegerType(16);
    IntegerType i32Type = b.getIntegerType(32);

    q8 = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i8Type, nullptr,
                              std::numeric_limits<int8_t>::min(),
                              std::numeric_limits<int8_t>::max()),
        CandidateQuantizedType::Scheme::UniformPerLayer);
    q16 = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i16Type, nullptr,
                              std::numeric_limits<int16_t>::min(),
                              std::numeric_limits<int16_t>::max()),
        CandidateQuantizedType::Scheme::UniformPerLayer);
    q32ExplicitFixedPoint = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i32Type, nullptr,
                              std::numeric_limits<int32_t>::min(),
                              std::numeric_limits<int32_t>::max()),
        CandidateQuantizedType::Scheme::UniformExplicitFixedPointScale);

    // Op handlers.
    addOpHandler<ConstantOp>(
        std::bind(&FxpMathTargetConfigImpl::handleConstant, this, _1, _2));
    addOpHandler<ReturnOp>(
        std::bind(&FxpMathTargetConfigImpl::handleTerminal, this, _1, _2));
    addOpHandler<quant::StatisticsOp>(
        std::bind(&FxpMathTargetConfigImpl::handleStats, this, _1, _2));

    // FxpMathOps.
    addOpHandler<RealAddEwOp>(
        std::bind(&FxpMathTargetConfigImpl::handleAdd, this, _1, _2));
    addOpHandler<RealMulEwOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMul, this, _1, _2));
    addOpHandler<RealMatMulOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMatMul, this, _1, _2));
    addOpHandler<RealMatMulBiasOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMatMulBias, this, _1, _2));

    // Require stats ops.
    addRequireStatsOp<RealAddEwOp>();
    addRequireStatsOp<RealSubEwOp>();
    addRequireStatsOp<RealDivEwOp>();
    addRequireStatsOp<RealMulEwOp>();
    addRequireStatsOp<RealMatMulOp>();
    addRequireStatsOp<RealMatMulBiasOp>();
  }

  bool isHandledType(Type t) const final {
    if (t.isa<FloatType>())
      return true;
    auto shapedType = t.dyn_cast<ShapedType>();
    return (shapedType && shapedType.getElementType().isa<FloatType>() &&
            (t.isa<VectorType>() || t.isa<TensorType>()));
  }

  void finalizeAnchors(CAGSlice &cag) const override {
    cag.enumerateImpliedConnections(
        [&](CAGAnchorNode *from, CAGAnchorNode *to) {
          UniformConstraintsBuilder(cag).coupleAnchors(from, to);
        });
  }

  void addValueIdentityOpByName(StringRef opName) override {
    addOpHandlerByName(
        opName,
        std::bind(&FxpMathTargetConfigImpl::handleValueIdentity, this, _1, _2));
  }

  void handleValueIdentity(Operation *op, CAGSlice &cag) const {
    assert(op->getNumResults() == 1);
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto resultNode = cag.getResultAnchor(op, 0);
    resultNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::DirectStorage);

    for (unsigned opIdx = 0, e = op->getNumOperands(); opIdx < e; ++opIdx) {
      if (!isHandledType(op->getOperand(opIdx)->getType()))
        continue;
      auto operandNode = cag.getOperandAnchor(op, opIdx);
      operandNode->setTypeTransformRule(
          CAGAnchorNode::TypeTransformRule::DirectStorage);
      UniformConstraintsBuilder(cag).coupleAnchors(operandNode, resultNode);
    }
  }

  void handleConstant(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto resultNode = cag.getResultAnchor(op, 0);
    resultNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::ExpressedOnly);
    Attribute valueAttr;
    if (!matchPattern(op, m_Constant(&valueAttr))) {
      return;
    }

    AttributeTensorStatistics stats(valueAttr);
    TensorAxisStatistics layerStats;
    if (!stats.get(layerStats)) {
      op->emitOpError("could not compute statistics");
      return;
    }

    UniformConstraintsBuilder(cag).applyStats(resultNode, layerStats);
  }

  void handleTerminal(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getOperand(0)->getType()))
      return;
    auto operandNode = cag.getOperandAnchor(op, 0);
    operandNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::ExpressedOnly);
  }

  void handleStats(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto argNode = cag.getOperandAnchor(op, 0);
    auto resultNode = cag.getResultAnchor(op, 0);
    UniformConstraintsBuilder(cag).coupleAnchors(argNode, resultNode);

    TensorAxisStatistics layerStats;
    auto statsOp = cast<quant::StatisticsOp>(op);
    auto layerStatsAttr = statsOp.layerStats();
    layerStats.minValue =
        layerStatsAttr.getValue({0}).cast<FloatAttr>().getValueAsDouble();
    layerStats.maxValue =
        layerStatsAttr.getValue({1}).cast<FloatAttr>().getValueAsDouble();
    UniformConstraintsBuilder(cag).applyStats(resultNode,
                                              std::move(layerStats));
  }

  void handleAdd(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Add supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    // NOTE: We couple the add such that the scale/zeroPoint match between
    // both args and the result. This is overly constrained in that it is
    // possible to write efficient add kernels with a bit more freedom (i.e.
    // zeroPoints can vary, scales can differ by a power of two, etc).
    // However, fully coupled yields the simples solutions on the fast path.
    // Further efficiency can be had by constraining the zeroPoint to 0, but
    // there isn't a constraint for this yet (and there are tradeoffs).
    UniformConstraintsBuilder(cag).coupleAnchors(lhs, resultNode);
    UniformConstraintsBuilder(cag).coupleAnchors(rhs, resultNode);
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMul(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMatMul(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMatMulBias(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto bias = cag.getOperandAnchor(op, 2);
    bias->getUniformMetadata().disabledCandidateTypes =
        getCandidateTypeDisabledExceptMask({q32ExplicitFixedPoint});

    auto resultNode = cag.getResultAnchor(op, 0);
    UniformConstraintsBuilder(cag).propagateExplicitScale(resultNode, bias);

    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void addRealMathOptionalConstraints(Operation *op, CAGAnchorNode *anchor,
                                      CAGSlice &cag) const {
    // TODO: It would be nice if these all extended some base trait instead
    // of requiring name lookup.
    auto clampMinAttr = op->getAttrOfType<FloatAttr>("clamp_min");
    auto clampMaxAttr = op->getAttrOfType<FloatAttr>("clamp_max");

    if (clampMinAttr || clampMaxAttr) {
      auto nan = APFloat::getQNaN(APFloat::IEEEdouble());
      auto clampMin = clampMinAttr ? clampMinAttr.getValue() : nan;
      auto clampMax = clampMaxAttr ? clampMaxAttr.getValue() : nan;
      UniformConstraintsBuilder(cag).clamp(anchor, clampMin, clampMax);
    }
  }

  unsigned q8;
  unsigned q16;
  unsigned q32ExplicitFixedPoint;
};

} // anonymous namespace

std::unique_ptr<FxpMathTargetConfig>
FxpMathTargetConfig::create(SolverContext &context) {
  return llvm::make_unique<FxpMathTargetConfigImpl>(context);
}
<commit_msg>    Avoid dyn_cast to ShapedType<commit_after>//===- FxpMathConfig.cpp - Reference fixed point config -------------------===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
//
// This file defines a TargetConfiguration for reference fixed-point math
// quantization scheme based on the FxpMathOps (plus a small category of
// extension ops that can be added from other dialects).
//
//===----------------------------------------------------------------------===//

#include "mlir/Quantizer/Configurations/FxpMathConfig.h"

#include "mlir/Dialect/FxpMathOps/FxpMathOps.h"
#include "mlir/Dialect/QuantOps/QuantOps.h"
#include "mlir/Dialect/QuantOps/QuantTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Quantizer/Support/ConstraintAnalysisGraph.h"
#include "mlir/Quantizer/Support/Metadata.h"
#include "mlir/Quantizer/Support/Statistics.h"
#include "mlir/Quantizer/Support/UniformConstraints.h"
#include "mlir/StandardOps/Ops.h"

using namespace mlir;
using namespace mlir::quantizer;
using namespace mlir::fxpmath;
using namespace mlir::quant;
using namespace std::placeholders;

namespace {

struct FxpMathTargetConfigImpl : public FxpMathTargetConfig {
  FxpMathTargetConfigImpl(SolverContext &context)
      : FxpMathTargetConfig(context) {
    Builder b(&context.getMlirContext());
    IntegerType i8Type = b.getIntegerType(8);
    IntegerType i16Type = b.getIntegerType(16);
    IntegerType i32Type = b.getIntegerType(32);

    q8 = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i8Type, nullptr,
                              std::numeric_limits<int8_t>::min(),
                              std::numeric_limits<int8_t>::max()),
        CandidateQuantizedType::Scheme::UniformPerLayer);
    q16 = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i16Type, nullptr,
                              std::numeric_limits<int16_t>::min(),
                              std::numeric_limits<int16_t>::max()),
        CandidateQuantizedType::Scheme::UniformPerLayer);
    q32ExplicitFixedPoint = addCandidateType(
        AnyQuantizedType::get(QuantizationFlags::Signed, i32Type, nullptr,
                              std::numeric_limits<int32_t>::min(),
                              std::numeric_limits<int32_t>::max()),
        CandidateQuantizedType::Scheme::UniformExplicitFixedPointScale);

    // Op handlers.
    addOpHandler<ConstantOp>(
        std::bind(&FxpMathTargetConfigImpl::handleConstant, this, _1, _2));
    addOpHandler<ReturnOp>(
        std::bind(&FxpMathTargetConfigImpl::handleTerminal, this, _1, _2));
    addOpHandler<quant::StatisticsOp>(
        std::bind(&FxpMathTargetConfigImpl::handleStats, this, _1, _2));

    // FxpMathOps.
    addOpHandler<RealAddEwOp>(
        std::bind(&FxpMathTargetConfigImpl::handleAdd, this, _1, _2));
    addOpHandler<RealMulEwOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMul, this, _1, _2));
    addOpHandler<RealMatMulOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMatMul, this, _1, _2));
    addOpHandler<RealMatMulBiasOp>(
        std::bind(&FxpMathTargetConfigImpl::handleMatMulBias, this, _1, _2));

    // Require stats ops.
    addRequireStatsOp<RealAddEwOp>();
    addRequireStatsOp<RealSubEwOp>();
    addRequireStatsOp<RealDivEwOp>();
    addRequireStatsOp<RealMulEwOp>();
    addRequireStatsOp<RealMatMulOp>();
    addRequireStatsOp<RealMatMulBiasOp>();
  }

  bool isHandledType(Type t) const final {
    if (t.isa<FloatType>())
      return true;
    return (t.isa<VectorType>() || t.isa<TensorType>()) &&
           t.cast<ShapedType>().getElementType().isa<FloatType>();
  }

  void finalizeAnchors(CAGSlice &cag) const override {
    cag.enumerateImpliedConnections(
        [&](CAGAnchorNode *from, CAGAnchorNode *to) {
          UniformConstraintsBuilder(cag).coupleAnchors(from, to);
        });
  }

  void addValueIdentityOpByName(StringRef opName) override {
    addOpHandlerByName(
        opName,
        std::bind(&FxpMathTargetConfigImpl::handleValueIdentity, this, _1, _2));
  }

  void handleValueIdentity(Operation *op, CAGSlice &cag) const {
    assert(op->getNumResults() == 1);
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto resultNode = cag.getResultAnchor(op, 0);
    resultNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::DirectStorage);

    for (unsigned opIdx = 0, e = op->getNumOperands(); opIdx < e; ++opIdx) {
      if (!isHandledType(op->getOperand(opIdx)->getType()))
        continue;
      auto operandNode = cag.getOperandAnchor(op, opIdx);
      operandNode->setTypeTransformRule(
          CAGAnchorNode::TypeTransformRule::DirectStorage);
      UniformConstraintsBuilder(cag).coupleAnchors(operandNode, resultNode);
    }
  }

  void handleConstant(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto resultNode = cag.getResultAnchor(op, 0);
    resultNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::ExpressedOnly);
    Attribute valueAttr;
    if (!matchPattern(op, m_Constant(&valueAttr))) {
      return;
    }

    AttributeTensorStatistics stats(valueAttr);
    TensorAxisStatistics layerStats;
    if (!stats.get(layerStats)) {
      op->emitOpError("could not compute statistics");
      return;
    }

    UniformConstraintsBuilder(cag).applyStats(resultNode, layerStats);
  }

  void handleTerminal(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getOperand(0)->getType()))
      return;
    auto operandNode = cag.getOperandAnchor(op, 0);
    operandNode->setTypeTransformRule(
        CAGAnchorNode::TypeTransformRule::ExpressedOnly);
  }

  void handleStats(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto argNode = cag.getOperandAnchor(op, 0);
    auto resultNode = cag.getResultAnchor(op, 0);
    UniformConstraintsBuilder(cag).coupleAnchors(argNode, resultNode);

    TensorAxisStatistics layerStats;
    auto statsOp = cast<quant::StatisticsOp>(op);
    auto layerStatsAttr = statsOp.layerStats();
    layerStats.minValue =
        layerStatsAttr.getValue({0}).cast<FloatAttr>().getValueAsDouble();
    layerStats.maxValue =
        layerStatsAttr.getValue({1}).cast<FloatAttr>().getValueAsDouble();
    UniformConstraintsBuilder(cag).applyStats(resultNode,
                                              std::move(layerStats));
  }

  void handleAdd(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Add supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    // NOTE: We couple the add such that the scale/zeroPoint match between
    // both args and the result. This is overly constrained in that it is
    // possible to write efficient add kernels with a bit more freedom (i.e.
    // zeroPoints can vary, scales can differ by a power of two, etc).
    // However, fully coupled yields the simples solutions on the fast path.
    // Further efficiency can be had by constraining the zeroPoint to 0, but
    // there isn't a constraint for this yet (and there are tradeoffs).
    UniformConstraintsBuilder(cag).coupleAnchors(lhs, resultNode);
    UniformConstraintsBuilder(cag).coupleAnchors(rhs, resultNode);
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMul(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMatMul(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto resultNode = cag.getResultAnchor(op, 0);
    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void handleMatMulBias(Operation *op, CAGSlice &cag) const {
    if (!isHandledType(op->getResult(0)->getType()))
      return;

    auto lhs = cag.getOperandAnchor(op, 0);
    auto rhs = cag.getOperandAnchor(op, 1);
    auto bias = cag.getOperandAnchor(op, 2);
    bias->getUniformMetadata().disabledCandidateTypes =
        getCandidateTypeDisabledExceptMask({q32ExplicitFixedPoint});

    auto resultNode = cag.getResultAnchor(op, 0);
    UniformConstraintsBuilder(cag).propagateExplicitScale(resultNode, bias);

    // Mul supports 8/16 bit math.
    llvm::SmallBitVector disableMask =
        getCandidateTypeDisabledExceptMask({q8, q16});
    lhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    rhs->getUniformMetadata().disabledCandidateTypes = disableMask;
    resultNode->getUniformMetadata().disabledCandidateTypes = disableMask;
    addRealMathOptionalConstraints(op, resultNode, cag);
  }

  void addRealMathOptionalConstraints(Operation *op, CAGAnchorNode *anchor,
                                      CAGSlice &cag) const {
    // TODO: It would be nice if these all extended some base trait instead
    // of requiring name lookup.
    auto clampMinAttr = op->getAttrOfType<FloatAttr>("clamp_min");
    auto clampMaxAttr = op->getAttrOfType<FloatAttr>("clamp_max");

    if (clampMinAttr || clampMaxAttr) {
      auto nan = APFloat::getQNaN(APFloat::IEEEdouble());
      auto clampMin = clampMinAttr ? clampMinAttr.getValue() : nan;
      auto clampMax = clampMaxAttr ? clampMaxAttr.getValue() : nan;
      UniformConstraintsBuilder(cag).clamp(anchor, clampMin, clampMax);
    }
  }

  unsigned q8;
  unsigned q16;
  unsigned q32ExplicitFixedPoint;
};

} // anonymous namespace

std::unique_ptr<FxpMathTargetConfig>
FxpMathTargetConfig::create(SolverContext &context) {
  return llvm::make_unique<FxpMathTargetConfigImpl>(context);
}
<|endoftext|>


<commit_before><commit_msg>vcl: Use glScissor for rectangular clip regions<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: soicon.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: ssa $ $Date: 2001-04-27 15:29:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SV_SOICON_HXX
#define _SV_SOICON_HXX

// base name of a custom icon function (must be declared extern "C")
// the iconid must be directly appended, eg: vcl_customIcon100
#define VCL_CUSTOM_ICON_BASE  "vcl_customIcon"

// type of the custom icon function
typedef void VCL_CUSTOM_ICON_FN( char **&, char **&, char **&, char **&);

class SalDisplay;
class SalBitmap;
class Bitmap;

BOOL SelectAppIconPixmap( SalDisplay *pDisplay, USHORT nIcon, USHORT iconSize,
                          Pixmap& icon_pixmap, Pixmap& icon_mask );

BOOL ReadXPMFile( Display*, const String&, SalBitmap*&, SalBitmap*& );
BOOL ReadXBMFile( Display*, const String&, SalBitmap*& );

#endif
<commit_msg>INTEGRATION: CWS wmicons (1.2.772); FILE MERGED 2005/02/24 14:14:01 obr 1.2.772.1: #i37167# window manager icons now loaded from resource<commit_after>/*************************************************************************
 *
 *  $RCSfile: soicon.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-03 19:57:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SV_SOICON_HXX
#define _SV_SOICON_HXX

class SalDisplay;
class SalBitmap;
class Bitmap;

BOOL SelectAppIconPixmap( SalDisplay *pDisplay, USHORT nIcon, USHORT iconSize,
                          Pixmap& icon_pixmap, Pixmap& icon_mask );
#endif
<|endoftext|>


<commit_before>#ifndef __BH_VE_CPU_SPECIALIZER
#define __BH_VE_CPU_SPECIALIZER

#include <ctemplate/template.h>

static ctemplate::Strip strip_mode = ctemplate::STRIP_BLANK_LINES;

void specializer_init()
{
    ctemplate::mutable_default_template_cache()->SetTemplateRootDirectory(template_path);
    ctemplate::LoadTemplate("ewise.cont.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.2d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.3d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("kernel.tpl", strip_mode);
    ctemplate::LoadTemplate("license.tpl", strip_mode);
    ctemplate::LoadTemplate("random.cont.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("range.cont.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.2d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.3d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("scan.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("scan.strided.nd.tpl", strip_mode);
    ctemplate::mutable_default_template_cache()->Freeze();
}

/**
 *  Choose the template.
 *
 *  Contract: Do not call this for system or extension operations.
 */
string template_filename(block_t& block, int pc, bh_intp optimized)
{
    string tpl_ndim   = "nd.",
           tpl_opcode,
           tpl_layout = "strided.";

    tac_t* tac = &block.program[pc];
    int ndim = (tac->op == REDUCE)         ? \
               block.scope[tac->in1].ndim : \
               block.scope[tac->out].ndim;
    int lmask = block.lmask[pc];

    switch (tac->op) {                    // OPCODE_SWITCH
        case MAP:

            tpl_opcode  = "ewise.";
            if ((optimized) && ((lmask == LMASK_CC) || \
                                (lmask == LMASK_CK))) {
                tpl_layout  = "cont.";
            } else if ((optimized) && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if ((optimized) && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if ((optimized) && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case ZIP:
            tpl_opcode  = "ewise.";
            if ((optimized) && (
                (lmask == LMASK_CCC) || (lmask == LMASK_CKC) || (lmask == LMASK_CCK)
                )) {
                tpl_layout  = "cont.";
            } else if ((optimized) && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if ((optimized) && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if ((optimized) && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case SCAN:
            tpl_opcode = "scan.";
            if (optimized && (ndim == 1)) {
                tpl_ndim = "1d.";
            }
            break;

        case REDUCE:
            tpl_opcode = "reduce.";
            if (optimized && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if (optimized && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if (optimized && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case GENERATE:
            switch(tac->oper) {
                case RANDOM:
                    tpl_opcode = "random.";
                    break;
                case RANGE:
                    tpl_opcode = "range.";
                default:
                    printf("Operator x is not supported with operation y\n");
            }
            tpl_layout = "cont.";
            break;

        default:
            printf("template_filename: Err=[Unsupported operation %d.]\n", tac->oper);
            throw runtime_error("template_filename: No template for opcode.");
    }

    return tpl_opcode + tpl_layout + tpl_ndim  + "tpl";
}

/**
 *  Construct the c-sourcecode for the given block.
 *
 *  NOTE: System opcodes are ignored.
 *
 *  @param optimized The level of optimizations to apply to the generated code.
 *  @param block The block to generate sourcecode for.
 *  @return The generated sourcecode.
 *
 */
string specialize(block_t& block, bh_intp const optimized) {

    string sourcecode  = "";

    ctemplate::TemplateDictionary kernel_d("KERNEL");   // Kernel - function wrapping code
    kernel_d.SetValue("SYMBOL", block.symbol);

    for(int j=0; j<block.ninstr; ++j) {

        //
        // Grab the tacuction for which to generate sourcecode
        tac_t *tac = &block.program[j];

        //
        // Skip code generation for system and extensions
        if ((tac->op == SYSTEM) || (tac->op == EXTENSION)) {
            continue;
        }

        //
        // The operation (ewise, reduction, scan, random, range).
        ctemplate::TemplateDictionary* operation_d = kernel_d.AddIncludeDictionary("OPERATIONS");
        string tf = template_filename(
            block,
            j,
            optimized
        );
        operation_d->SetFilename(tf);

        //
        // The operator +, -, /, min, max, sin, sqrt, etc...
        //
        ctemplate::TemplateDictionary* operator_d = operation_d->AddSectionDictionary("OPERATORS");
        operator_d->SetValue("OPERATOR", operator_cexpr(tac->op, tac->oper, block.scope[tac->out].type));

        //
        // Reduction and scan specific expansions
        // TODO: fix for multiple tacuctions
        if ((tac->op == REDUCE) || (tac->op == SCAN)) {
            operation_d->SetValue("TYPE_OUTPUT", enum_to_ctypestr(block.scope[tac->out].type));
            operation_d->SetValue("TYPE_INPUT",  enum_to_ctypestr(block.scope[tac->in1].type));
            operation_d->SetValue("TYPE_AXIS",  "int64_t");
            if (tac->oper == ADD) {
                operation_d->SetValue("NEUTRAL_ELEMENT", std::to_string(0));
            } else if (tac->oper == MULTIPLY) {
                operation_d->SetValue("NEUTRAL_ELEMENT", std::to_string(1));
            }
        }
        operation_d->SetValue("NR_OUTPUT", std::to_string(tac->out));
        operation_d->SetValue("NR_FINPUT", std::to_string(tac->in1));  // Not all have
        operation_d->SetValue("NR_SINPUT", std::to_string(tac->in2));  // Not all have

        //
        // Fill out the tacuction operands globally such that they
        // are available to both for the kernel argument unpacking, the operations and the operators.
        //
        // TODO: this should actually distinguish between the total set of operands
        // and those used for a single tacuction depending on the amount of loops that can be
        // fused
        //
        int nops_tac = noperands(tac);
        for(int i=0; i<nops_tac; ++i) {        // Operand dict
            ctemplate::TemplateDictionary* argument_d = kernel_d.AddSectionDictionary("ARGUMENT");
            ctemplate::TemplateDictionary* operand_d  = operation_d->AddSectionDictionary("OPERAND");

            argument_d->SetValue("TYPE", enum_to_ctypestr(block.scope[tac->out].type));
            argument_d->SetIntValue("NR", tac->out);

            operand_d->SetValue("TYPE", enum_to_ctypestr(block.scope[tac->out].type));
            operand_d->SetIntValue("NR",  tac->out);
            if (block.scope[tac->out].layout != CONSTANT) {
                argument_d->ShowSection("ARRAY");
                operand_d->ShowSection("ARRAY");
            }
        }
    }

    //
    // Fill out the template and return the generated sourcecode
    //
    ctemplate::ExpandTemplate(
        "kernel.tpl",
        strip_mode,
        &kernel_d,
        &sourcecode
    );

    return sourcecode;
}

/**
 *  Create a symbol for the kernel.
 *
 *  NOTE: System and extension opcodes are ignored.
 *        If a kernel consists of nothing but system and/or extension
 *        opcodes then the symbol will be the empty string "".
 */
bool symbolize(bh_kernel_t &kernel, bh_intp const optimized) {

    std::string symbol_opcode,
                symbol_lmask,
                symbol_tsig,
                symbol_ndim;

    kernel.symbol   = "";

    for (int i=0; i<kernel.ninstr; ++i) {
        tac_t* tac = &kernel.program[i];

        // Do not include system opcodes in the kernel symbol.
        if ((tac->op == SYSTEM) || (tac->op == EXTENSION)) {
            continue;
        }

        symbol_opcode  += std::string(bh_opcode_to_cstr_short(tac->op));
        symbol_tsig    += std::string(bh_typesig_to_shorthand(kernel.tsig[i]));
        symbol_lmask   += std::string(bh_layoutmask_to_shorthand(kernel.lmask[i]));

        int ndim = kernel.scope[tac->out].ndim;
        if (tac->op == REDUCE) {
            ndim = kernel.scope[tac->in1].ndim;
        }
        if (optimized && (ndim <= 3)) {        // Optimized
            symbol_ndim += std::to_string(ndim);
        } else {
            symbol_ndim += std::string("N");
        }
        symbol_ndim += "D";

        kernel.tsig[i]  = tsig;
        kernel.lmask[i] = lmask;
    }

    if (kernel.omask == (HAS_ARRAY_OP)) {
        kernel.symbol = "BH_" + \
                        symbol_opcode  + "_" +\
                        symbol_tsig    + "_" +\
                        symbol_lmask   + "_" +\
                        symbol_ndim;
    }
    return true;
}

#endif
<commit_msg>cpu: Kernels are now "blocks" until they are codegenerated...<commit_after>#ifndef __BH_VE_CPU_SPECIALIZER
#define __BH_VE_CPU_SPECIALIZER

#include <ctemplate/template.h>

static ctemplate::Strip strip_mode = ctemplate::STRIP_BLANK_LINES;

void specializer_init()
{
    ctemplate::mutable_default_template_cache()->SetTemplateRootDirectory(template_path);
    ctemplate::LoadTemplate("ewise.cont.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.2d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.3d.tpl", strip_mode);
    ctemplate::LoadTemplate("ewise.strided.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("kernel.tpl", strip_mode);
    ctemplate::LoadTemplate("license.tpl", strip_mode);
    ctemplate::LoadTemplate("random.cont.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("range.cont.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.2d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.3d.tpl", strip_mode);
    ctemplate::LoadTemplate("reduce.strided.nd.tpl", strip_mode);
    ctemplate::LoadTemplate("scan.strided.1d.tpl", strip_mode);
    ctemplate::LoadTemplate("scan.strided.nd.tpl", strip_mode);
    ctemplate::mutable_default_template_cache()->Freeze();
}

/**
 *  Choose the template.
 *
 *  Contract: Do not call this for system or extension operations.
 */
string template_filename(block_t& block, int pc, bh_intp optimized)
{
    string tpl_ndim   = "nd.",
           tpl_opcode,
           tpl_layout = "strided.";

    tac_t* tac = &block.program[pc];
    int ndim = (tac->op == REDUCE)         ? \
               block.scope[tac->in1].ndim : \
               block.scope[tac->out].ndim;
    int lmask = block.lmask[pc];

    switch (tac->op) {                    // OPCODE_SWITCH
        case MAP:

            tpl_opcode  = "ewise.";
            if ((optimized) && ((lmask == LMASK_CC) || \
                                (lmask == LMASK_CK))) {
                tpl_layout  = "cont.";
            } else if ((optimized) && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if ((optimized) && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if ((optimized) && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case ZIP:
            tpl_opcode  = "ewise.";
            if ((optimized) && (
                (lmask == LMASK_CCC) || (lmask == LMASK_CKC) || (lmask == LMASK_CCK)
                )) {
                tpl_layout  = "cont.";
            } else if ((optimized) && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if ((optimized) && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if ((optimized) && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case SCAN:
            tpl_opcode = "scan.";
            if (optimized && (ndim == 1)) {
                tpl_ndim = "1d.";
            }
            break;

        case REDUCE:
            tpl_opcode = "reduce.";
            if (optimized && (ndim == 1)) {
                tpl_ndim = "1d.";
            } else if (optimized && (ndim == 2)) {
                tpl_ndim = "2d.";
            } else if (optimized && (ndim == 3)) {
                tpl_ndim = "3d.";
            }
            break;

        case GENERATE:
            switch(tac->oper) {
                case RANDOM:
                    tpl_opcode = "random.";
                    break;
                case RANGE:
                    tpl_opcode = "range.";
                default:
                    printf("Operator x is not supported with operation y\n");
            }
            tpl_layout = "cont.";
            break;

        default:
            printf("template_filename: Err=[Unsupported operation %d.]\n", tac->oper);
            throw runtime_error("template_filename: No template for opcode.");
    }

    return tpl_opcode + tpl_layout + tpl_ndim  + "tpl";
}

/**
 *  Construct the c-sourcecode for the given block.
 *
 *  NOTE: System opcodes are ignored.
 *
 *  @param optimized The level of optimizations to apply to the generated code.
 *  @param block The block to generate sourcecode for.
 *  @return The generated sourcecode.
 *
 */
string specialize(block_t& block, bh_intp const optimized) {

    string sourcecode  = "";

    ctemplate::TemplateDictionary kernel_d("KERNEL");   // Kernel - function wrapping code
    kernel_d.SetValue("SYMBOL", block.symbol);

    for(int j=0; j<block.ninstr; ++j) {

        //
        // Grab the tacuction for which to generate sourcecode
        tac_t *tac = &block.program[j];

        //
        // Skip code generation for system and extensions
        if ((tac->op == SYSTEM) || (tac->op == EXTENSION)) {
            continue;
        }

        //
        // The operation (ewise, reduction, scan, random, range).
        ctemplate::TemplateDictionary* operation_d = kernel_d.AddIncludeDictionary("OPERATIONS");
        string tf = template_filename(
            block,
            j,
            optimized
        );
        operation_d->SetFilename(tf);

        //
        // The operator +, -, /, min, max, sin, sqrt, etc...
        //
        ctemplate::TemplateDictionary* operator_d = operation_d->AddSectionDictionary("OPERATORS");
        operator_d->SetValue("OPERATOR", operator_cexpr(tac->op, tac->oper, block.scope[tac->out].type));

        //
        // Reduction and scan specific expansions
        // TODO: fix for multiple tacuctions
        if ((tac->op == REDUCE) || (tac->op == SCAN)) {
            operation_d->SetValue("TYPE_OUTPUT", enum_to_ctypestr(block.scope[tac->out].type));
            operation_d->SetValue("TYPE_INPUT",  enum_to_ctypestr(block.scope[tac->in1].type));
            operation_d->SetValue("TYPE_AXIS",  "int64_t");
            if (tac->oper == ADD) {
                operation_d->SetValue("NEUTRAL_ELEMENT", std::to_string(0));
            } else if (tac->oper == MULTIPLY) {
                operation_d->SetValue("NEUTRAL_ELEMENT", std::to_string(1));
            }
        }
        operation_d->SetValue("NR_OUTPUT", std::to_string(tac->out));
        operation_d->SetValue("NR_FINPUT", std::to_string(tac->in1));  // Not all have
        operation_d->SetValue("NR_SINPUT", std::to_string(tac->in2));  // Not all have

        //
        // Fill out the tacuction operands globally such that they
        // are available to both for the kernel argument unpacking, the operations and the operators.
        //
        // TODO: this should actually distinguish between the total set of operands
        // and those used for a single tacuction depending on the amount of loops that can be
        // fused
        //
        int nops_tac = noperands(tac);
        for(int i=0; i<nops_tac; ++i) {        // Operand dict
            ctemplate::TemplateDictionary* argument_d = kernel_d.AddSectionDictionary("ARGUMENT");
            ctemplate::TemplateDictionary* operand_d  = operation_d->AddSectionDictionary("OPERAND");

            argument_d->SetValue("TYPE", enum_to_ctypestr(block.scope[tac->out].type));
            argument_d->SetIntValue("NR", tac->out);

            operand_d->SetValue("TYPE", enum_to_ctypestr(block.scope[tac->out].type));
            operand_d->SetIntValue("NR",  tac->out);
            if (block.scope[tac->out].layout != CONSTANT) {
                argument_d->ShowSection("ARRAY");
                operand_d->ShowSection("ARRAY");
            }
        }
    }

    //
    // Fill out the template and return the generated sourcecode
    //
    ctemplate::ExpandTemplate(
        "kernel.tpl",
        strip_mode,
        &kernel_d,
        &sourcecode
    );

    return sourcecode;
}

/**
 *  Create a symbol for the kernel.
 *
 *  NOTE: System and extension opcodes are ignored.
 *        If a block consists of nothing but system and/or extension
 *        opcodes then the symbol will be the empty string "".
 */
bool symbolize(block_t &block, bh_intp const optimized) {

    std::string symbol_opcode,
                symbol_lmask,
                symbol_tsig,
                symbol_ndim;

    block.symbol   = "";

    for (int i=0; i<block.ninstr; ++i) {
        tac_t* tac = &block.program[i];

        // Do not include system opcodes in the kernel symbol.
        if ((tac->op == SYSTEM) || (tac->op == EXTENSION)) {
            continue;
        }

        symbol_opcode  += std::string(bh_opcode_to_cstr_short(tac->op));
        symbol_tsig    += std::string(bh_typesig_to_shorthand(block.tsig[i]));
        symbol_lmask   += std::string(bh_layoutmask_to_shorthand(block.lmask[i]));

        int ndim = block.scope[tac->out].ndim;
        if (tac->op == REDUCE) {
            ndim = block.scope[tac->in1].ndim;
        }
        if (optimized && (ndim <= 3)) {        // Optimized
            symbol_ndim += std::to_string(ndim);
        } else {
            symbol_ndim += std::string("N");
        }
        symbol_ndim += "D";

        block.tsig[i]  = tsig;
        block.lmask[i] = lmask;
    }

    if (block.omask == (HAS_ARRAY_OP)) {
        block.symbol = "BH_" + \
                        symbol_opcode  + "_" +\
                        symbol_tsig    + "_" +\
                        symbol_lmask   + "_" +\
                        symbol_ndim;
    }
    return true;
}

#endif
<|endoftext|>