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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <tools/rtti.hxx>
#include <SwUndoField.hxx>
#include <swundo.hxx>
#include <doc.hxx>
#include <txtfld.hxx>
#include <fldbas.hxx>
#include <ndtxt.hxx>
#include <fmtfld.hxx>
#include <dbfld.hxx>
using namespace com::sun::star::uno;

SwUndoField::SwUndoField(const SwPosition & rPos)
    : SwUndo(UNDO_FIELD)
{
    nNodeIndex = rPos.nNode.GetIndex();
    nOffset = rPos.nContent.GetIndex();
    pDoc = rPos.GetDoc();
}

SwUndoField::~SwUndoField()
{
}

SwPosition SwUndoField::GetPosition()
{
    SwNode * pNode = pDoc->GetNodes()[nNodeIndex];
    SwNodeIndex aNodeIndex(*pNode);
    SwIndex aIndex(pNode->GetCntntNode(), nOffset);
    SwPosition aResult(aNodeIndex, aIndex);

    return aResult;
}

SwUndoFieldFromDoc::SwUndoFieldFromDoc(const SwPosition & rPos,
                                       const SwField & _aOldField,
                         const SwField & _aNewField,
                         SwMsgPoolItem * _pHnt, BOOL _bUpdate)
    : SwUndoField(rPos), pOldField(_aOldField.Copy()),
      pNewField(_aNewField.Copy()), pHnt(_pHnt),
      bUpdate(_bUpdate)
{
    ASSERT(pOldField, "No old field!");
    ASSERT(pNewField, "No new field!");
    ASSERT(pDoc, "No document!");
}

SwUndoFieldFromDoc::~SwUndoFieldFromDoc()
{
    delete pOldField;
    delete pNewField;
}

void SwUndoFieldFromDoc::Undo(SwUndoIter & rIt)
{
    SwTxtFld * pTxtFld = SwDoc::GetTxtFld(GetPosition());
    const SwField * pField = pTxtFld->GetFld().GetFld();

    if (pField)
    {
        BOOL bUndo = pDoc->DoesUndo();

        pDoc->DoUndo(FALSE);
        pDoc->UpdateFld(pTxtFld, *pOldField, pHnt, bUpdate);
        pDoc->DoUndo(bUndo);
    }
}

void SwUndoFieldFromDoc::Redo(SwUndoIter & rIt)
{
    SwTxtFld * pTxtFld = SwDoc::GetTxtFld(GetPosition());
    const SwField * pField = pTxtFld->GetFld().GetFld();

    if (pField)
    {
        BOOL bUndo = pDoc->DoesUndo();

        pDoc->DoUndo(FALSE);
        pDoc->UpdateFld(pTxtFld, *pNewField, pHnt, bUpdate);
        pDoc->DoUndo(bUndo);
    }
}

void SwUndoFieldFromDoc::Repeat(SwUndoIter & rIt)
{
    Redo(rIt);
}

SwUndoFieldFromAPI::SwUndoFieldFromAPI(const SwPosition & rPos,
                                       const Any & rOldVal, const Any & rNewVal,
                                       BYTE _nMId)
    : SwUndoField(rPos), aOldVal(rOldVal), aNewVal(rNewVal), nMId(_nMId)
{
}

SwUndoFieldFromAPI::~SwUndoFieldFromAPI()
{
}

void SwUndoFieldFromAPI::Undo(SwUndoIter & rIter)
{
    SwField * pField = SwDoc::GetField(GetPosition());

    if (pField)
        pField->PutValue(aOldVal, nMId);
}

void SwUndoFieldFromAPI::Redo(SwUndoIter & rIter)
{
    SwField * pField = SwDoc::GetField(GetPosition());

    if (pField)
        pField->PutValue(aNewVal, nMId);
}

void SwUndoFieldFromAPI::Repeat(SwUndoIter & rIter)
{
    Redo(rIter);
}
<commit_msg>INTEGRATION: CWS swwarnings (1.7.222); FILE MERGED 2007/04/18 12:19:44 tl 1.7.222.3: #i69287# warning-free code 2007/04/11 07:02:56 tl 1.7.222.2: #i69287# warning-free code 2007/03/07 15:38:33 ama 1.7.222.1: #i69287#: Warning free<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SwUndoField.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 09:28:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <tools/rtti.hxx>
#include <SwUndoField.hxx>
#include <swundo.hxx>
#include <doc.hxx>
#include <txtfld.hxx>
#include <fldbas.hxx>
#include <ndtxt.hxx>
#include <fmtfld.hxx>
#include <dbfld.hxx>

using namespace ::com::sun::star::uno;

SwUndoField::SwUndoField(const SwPosition & rPos)
    : SwUndo(UNDO_FIELD)
{
    nNodeIndex = rPos.nNode.GetIndex();
    nOffset = rPos.nContent.GetIndex();
    pDoc = rPos.GetDoc();
}

SwUndoField::~SwUndoField()
{
}

SwPosition SwUndoField::GetPosition()
{
    SwNode * pNode = pDoc->GetNodes()[nNodeIndex];
    SwNodeIndex aNodeIndex(*pNode);
    SwIndex aIndex(pNode->GetCntntNode(), nOffset);
    SwPosition aResult(aNodeIndex, aIndex);

    return aResult;
}

SwUndoFieldFromDoc::SwUndoFieldFromDoc(const SwPosition & rPos,
                                       const SwField & _aOldField,
                         const SwField & _aNewField,
                         SwMsgPoolItem * _pHnt, BOOL _bUpdate)
    : SwUndoField(rPos), pOldField(_aOldField.Copy()),
      pNewField(_aNewField.Copy()), pHnt(_pHnt),
      bUpdate(_bUpdate)
{
    ASSERT(pOldField, "No old field!");
    ASSERT(pNewField, "No new field!");
    ASSERT(pDoc, "No document!");
}

SwUndoFieldFromDoc::~SwUndoFieldFromDoc()
{
    delete pOldField;
    delete pNewField;
}

void SwUndoFieldFromDoc::Undo( SwUndoIter& )
{
    SwTxtFld * pTxtFld = SwDoc::GetTxtFld(GetPosition());
    const SwField * pField = pTxtFld->GetFld().GetFld();

    if (pField)
    {
        BOOL bUndo = pDoc->DoesUndo();

        pDoc->DoUndo(FALSE);
        pDoc->UpdateFld(pTxtFld, *pOldField, pHnt, bUpdate);
        pDoc->DoUndo(bUndo);
    }
}

void SwUndoFieldFromDoc::Redo( SwUndoIter& )
{
    SwTxtFld * pTxtFld = SwDoc::GetTxtFld(GetPosition());
    const SwField * pField = pTxtFld->GetFld().GetFld();

    if (pField)
    {
        BOOL bUndo = pDoc->DoesUndo();

        pDoc->DoUndo(FALSE);
        pDoc->UpdateFld(pTxtFld, *pNewField, pHnt, bUpdate);
        pDoc->DoUndo(bUndo);
    }
}

void SwUndoFieldFromDoc::Repeat(SwUndoIter & rIt)
{
    Redo(rIt);
}

SwUndoFieldFromAPI::SwUndoFieldFromAPI(const SwPosition & rPos,
                                       const Any & rOldVal, const Any & rNewVal,
                                       USHORT _nWhich)
    : SwUndoField(rPos), aOldVal(rOldVal), aNewVal(rNewVal), nWhich(_nWhich)
{
}

SwUndoFieldFromAPI::~SwUndoFieldFromAPI()
{
}

void SwUndoFieldFromAPI::Undo( SwUndoIter& )
{
    SwField * pField = SwDoc::GetField(GetPosition());

    if (pField)
        pField->PutValue(aOldVal, nWhich);
}

void SwUndoFieldFromAPI::Redo( SwUndoIter& )
{
    SwField * pField = SwDoc::GetField(GetPosition());

    if (pField)
        pField->PutValue(aNewVal, nWhich);
}

void SwUndoFieldFromAPI::Repeat(SwUndoIter & rIter)
{
    Redo(rIter);
}
<|endoftext|>


<commit_before>//===-- AllocaHoisting.cpp - Hosist allocas to the entry block --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Hoist the alloca instructions in the non-entry blocks to the entry blocks.
//
//===----------------------------------------------------------------------===//

#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "NVPTXAllocaHoisting.h"

namespace llvm {

bool NVPTXAllocaHoisting::runOnFunction(Function &function) {
  bool               functionModified    = false;
  Function::iterator I                   = function.begin();
  TerminatorInst    *firstTerminatorInst = (I++)->getTerminator();

  for (Function::iterator E = function.end(); I != E; ++I) {
    for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE;) {
      AllocaInst *allocaInst = dyn_cast<AllocaInst>(BI++);
      if (allocaInst && isa<ConstantInt>(allocaInst->getArraySize())) {
        allocaInst->moveBefore(firstTerminatorInst);
        functionModified = true;
      }
    }
  }

  return functionModified;
}

char NVPTXAllocaHoisting::ID = 1;
RegisterPass<NVPTXAllocaHoisting> X("alloca-hoisting",
                                    "Hoisting alloca instructsion in non-entry "
                                    "blocks to the entry block");

FunctionPass *createAllocaHoisting() {
  return new NVPTXAllocaHoisting();
}

} // end namespace llvm
<commit_msg>Fix typos<commit_after>//===-- AllocaHoisting.cpp - Hoist allocas to the entry block --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Hoist the alloca instructions in the non-entry blocks to the entry blocks.
//
//===----------------------------------------------------------------------===//

#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "NVPTXAllocaHoisting.h"

namespace llvm {

bool NVPTXAllocaHoisting::runOnFunction(Function &function) {
  bool               functionModified    = false;
  Function::iterator I                   = function.begin();
  TerminatorInst    *firstTerminatorInst = (I++)->getTerminator();

  for (Function::iterator E = function.end(); I != E; ++I) {
    for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE;) {
      AllocaInst *allocaInst = dyn_cast<AllocaInst>(BI++);
      if (allocaInst && isa<ConstantInt>(allocaInst->getArraySize())) {
        allocaInst->moveBefore(firstTerminatorInst);
        functionModified = true;
      }
    }
  }

  return functionModified;
}

char NVPTXAllocaHoisting::ID = 1;
RegisterPass<NVPTXAllocaHoisting> X("alloca-hoisting",
                                    "Hoisting alloca instructions in non-entry "
                                    "blocks to the entry block");

FunctionPass *createAllocaHoisting() {
  return new NVPTXAllocaHoisting();
}

} // end namespace llvm
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#define EIGEN_NO_STATIC_ASSERT

#include "main.h"

template<typename MatrixType> void adjoint(const MatrixType& m)
{
  /* this test covers the following files:
     Transpose.h Conjugate.h Dot.h
  */
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = SquareMatrixType::Identity(rows, rows),
             square = SquareMatrixType::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             v3 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>(),
         s2 = internal::random<Scalar>();

  // check basic compatibility of adjoint, transpose, conjugate
  VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(),    m1);
  VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(),    m1);

  // check multiplicative behavior
  VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(),           m2.adjoint() * m1);
  VERIFY_IS_APPROX((s1 * m1).adjoint(),                     internal::conj(s1) * m1.adjoint());

  // check basic properties of dot, norm, norm2
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : std::max((s1 * v1 + s2 * v2).norm(),v3.norm());
  VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), ref));
  VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), ref));
  VERIFY_IS_APPROX(internal::conj(v1.dot(v2)),               v2.dot(v1));
  VERIFY_IS_APPROX(internal::real(v1.dot(v1)),                v1.squaredNorm());
  if(!NumTraits<Scalar>::IsInteger) {
    VERIFY_IS_APPROX(v1.squaredNorm(),                v1.norm() * v1.norm());
    // check normalized() and normalize()
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
    // normalize() returns a reference to *this
    v3 = v1;
    VERIFY_IS_APPROX(v1, v1.norm() * v3.normalize());
    VERIFY_IS_APPROX(v3, v1.normalized());
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
  }
  VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(vzero.dot(v1)),  static_cast<RealScalar>(1));

  // check compatibility of dot and adjoint

  ref = NumTraits<Scalar>::IsInteger ? 0 : std::max(std::max(v1.norm(),v2.norm()),std::max((square * v2).norm(),(square.adjoint() * v1).norm()));
  VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));

  // like in testBasicStuff, test operator() to check const-qualification
  Index r = internal::random<Index>(0, rows-1),
      c = internal::random<Index>(0, cols-1);
  VERIFY_IS_APPROX(m1.conjugate()(r,c), internal::conj(m1(r,c)));
  VERIFY_IS_APPROX(m1.adjoint()(c,r), internal::conj(m1(r,c)));

  if(!NumTraits<Scalar>::IsInteger)
  {
    // check that Random().normalized() works: tricky as the random xpr must be evaluated by
    // normalized() in order to produce a consistent result.
    VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
  }

  // check inplace transpose
  m3 = m1;
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.transpose());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1);

  // check inplace adjoint
  m3 = m1;
  m3.adjointInPlace();
  VERIFY_IS_APPROX(m3,m1.adjoint());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.conjugate());

  // check mixed dot product
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
  RealVectorType rv1 = RealVectorType::Random(rows);
  VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
}

void test_adjoint()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( adjoint(Matrix3d()) );
    CALL_SUBTEST_3( adjoint(Matrix4f()) );
    CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,50), internal::random<int>(1,50))) );
    CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,50), internal::random<int>(1,50))) );
    CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,50), internal::random<int>(1,50))) );
  }
  // test a large matrix only once
  CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );

#ifdef EIGEN_TEST_PART_4
  {
    MatrixXcf a(10,10), b(10,10);
    VERIFY_RAISES_ASSERT(a = a.transpose());
    VERIFY_RAISES_ASSERT(a = a.transpose() + b);
    VERIFY_RAISES_ASSERT(a = b + a.transpose());
    VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
    VERIFY_RAISES_ASSERT(a = a.adjoint());
    VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
    VERIFY_RAISES_ASSERT(a = b + a.adjoint());

    // no assertion should be triggered for these cases:
    a.transpose() = a.transpose();
    a.transpose() += a.transpose();
    a.transpose() += a.transpose() + b;
    a.transpose() = a.adjoint();
    a.transpose() += a.adjoint();
    a.transpose() += a.adjoint() + b;
  }
#endif
}

<commit_msg>adapt test to the change reverting normalize() to returning void<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#define EIGEN_NO_STATIC_ASSERT

#include "main.h"

template<typename MatrixType> void adjoint(const MatrixType& m)
{
  /* this test covers the following files:
     Transpose.h Conjugate.h Dot.h
  */
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = SquareMatrixType::Identity(rows, rows),
             square = SquareMatrixType::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             v3 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>(),
         s2 = internal::random<Scalar>();

  // check basic compatibility of adjoint, transpose, conjugate
  VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(),    m1);
  VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(),    m1);

  // check multiplicative behavior
  VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(),           m2.adjoint() * m1);
  VERIFY_IS_APPROX((s1 * m1).adjoint(),                     internal::conj(s1) * m1.adjoint());

  // check basic properties of dot, norm, norm2
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : std::max((s1 * v1 + s2 * v2).norm(),v3.norm());
  VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),     internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), ref));
  VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2),       s1*v3.dot(v1)+s2*v3.dot(v2), ref));
  VERIFY_IS_APPROX(internal::conj(v1.dot(v2)),               v2.dot(v1));
  VERIFY_IS_APPROX(internal::real(v1.dot(v1)),                v1.squaredNorm());
  if(!NumTraits<Scalar>::IsInteger) {
    VERIFY_IS_APPROX(v1.squaredNorm(),                v1.norm() * v1.norm());
    // check normalized() and normalize()
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
    v3 = v1;
    v3.normalize();
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
    VERIFY_IS_APPROX(v3, v1.normalized());
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
  }
  VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(vzero.dot(v1)),  static_cast<RealScalar>(1));

  // check compatibility of dot and adjoint

  ref = NumTraits<Scalar>::IsInteger ? 0 : std::max(std::max(v1.norm(),v2.norm()),std::max((square * v2).norm(),(square.adjoint() * v1).norm()));
  VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));

  // like in testBasicStuff, test operator() to check const-qualification
  Index r = internal::random<Index>(0, rows-1),
      c = internal::random<Index>(0, cols-1);
  VERIFY_IS_APPROX(m1.conjugate()(r,c), internal::conj(m1(r,c)));
  VERIFY_IS_APPROX(m1.adjoint()(c,r), internal::conj(m1(r,c)));

  if(!NumTraits<Scalar>::IsInteger)
  {
    // check that Random().normalized() works: tricky as the random xpr must be evaluated by
    // normalized() in order to produce a consistent result.
    VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
  }

  // check inplace transpose
  m3 = m1;
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.transpose());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1);

  // check inplace adjoint
  m3 = m1;
  m3.adjointInPlace();
  VERIFY_IS_APPROX(m3,m1.adjoint());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3,m1.conjugate());

  // check mixed dot product
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
  RealVectorType rv1 = RealVectorType::Random(rows);
  VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
  VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
}

void test_adjoint()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );
    CALL_SUBTEST_2( adjoint(Matrix3d()) );
    CALL_SUBTEST_3( adjoint(Matrix4f()) );
    CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,50), internal::random<int>(1,50))) );
    CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,50), internal::random<int>(1,50))) );
    CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,50), internal::random<int>(1,50))) );
  }
  // test a large matrix only once
  CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );

#ifdef EIGEN_TEST_PART_4
  {
    MatrixXcf a(10,10), b(10,10);
    VERIFY_RAISES_ASSERT(a = a.transpose());
    VERIFY_RAISES_ASSERT(a = a.transpose() + b);
    VERIFY_RAISES_ASSERT(a = b + a.transpose());
    VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
    VERIFY_RAISES_ASSERT(a = a.adjoint());
    VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
    VERIFY_RAISES_ASSERT(a = b + a.adjoint());

    // no assertion should be triggered for these cases:
    a.transpose() = a.transpose();
    a.transpose() += a.transpose();
    a.transpose() += a.transpose() + b;
    a.transpose() = a.adjoint();
    a.transpose() += a.adjoint();
    a.transpose() += a.adjoint() + b;
  }
#endif
}

<|endoftext|>


<commit_before>//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
//
// InductionVariableSimplify - Transform induction variables in a program
//   to all use a single cannonical induction variable per loop.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Analysis/InductionVariable.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/Type.h"
#include "llvm/ConstantVals.h"
#include "Support/STLExtras.h"

#if 0
#define DEBUG
#include "llvm/Analysis/Writer.h"
#endif

// InsertCast - Cast Val to Ty, setting a useful name on the cast if Val has a
// name...
//
static Instruction *InsertCast(Instruction *Val, const Type *Ty,
                               BasicBlock::iterator It) {
  Instruction *Cast = new CastInst(Val, Ty);
  if (Val->hasName()) Cast->setName(Val->getName()+"-casted");
  Val->getParent()->getInstList().insert(It, Cast);
  return Cast;
}

static bool TransformLoop(cfg::LoopInfo *Loops, cfg::Loop *Loop) {
  // Transform all subloops before this loop...
  bool Changed = reduce_apply_bool(Loop->getSubLoops().begin(),
                                   Loop->getSubLoops().end(),
                                   std::bind1st(ptr_fun(TransformLoop), Loops));
  // Get the header node for this loop.  All of the phi nodes that could be
  // induction variables must live in this basic block.
  BasicBlock *Header = (BasicBlock*)Loop->getBlocks().front();

  // Loop over all of the PHI nodes in the basic block, calculating the
  // induction variables that they represent... stuffing the induction variable
  // info into a vector...
  //
  vector<InductionVariable> IndVars;    // Induction variables for block
  for (BasicBlock::iterator I = Header->begin();
       PHINode *PN = dyn_cast<PHINode>(*I); ++I)
    IndVars.push_back(InductionVariable(PN, Loops));

  // If there are no phi nodes in this basic block, there can't be indvars...
  if (IndVars.empty()) return Changed;

  // Loop over the induction variables, looking for a cannonical induction
  // variable, and checking to make sure they are not all unknown induction
  // variables.
  //
  bool FoundIndVars = false;
  InductionVariable *Cannonical = 0;
  for (unsigned i = 0; i < IndVars.size(); ++i) {
    if (IndVars[i].InductionType == InductionVariable::Cannonical)
      Cannonical = &IndVars[i];
    if (IndVars[i].InductionType != InductionVariable::Unknown)
      FoundIndVars = true;
  }

  // No induction variables, bail early... don't add a cannonnical indvar
  if (!FoundIndVars) return Changed;

  // Okay, we want to convert other induction variables to use a cannonical
  // indvar.  If we don't have one, add one now...
  if (!Cannonical) {
    // Create the PHI node for the new induction variable
    PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar");

    // Insert the phi node at the end of the other phi nodes...
    Header->getInstList().insert(Header->begin()+IndVars.size(), PN);

    // Create the increment instruction to add one to the counter...
    Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
                                              ConstantUInt::get(Type::UIntTy,1),
                                              "add1-indvar");

    // Insert the add instruction after all of the PHI nodes...
    Header->getInstList().insert(Header->begin()+(IndVars.size()+1), Add);

    // Figure out which block is incoming and which is the backedge for the loop
    BasicBlock *Incoming, *BackEdgeBlock;
    BasicBlock::pred_iterator PI = Header->pred_begin();
    assert(PI != Header->pred_end() && "Loop headers should have 2 preds!");
    if (Loop->contains(*PI)) {  // First pred is back edge...
      BackEdgeBlock = *PI++;
      Incoming      = *PI++;
    } else {
      Incoming      = *PI++;
      BackEdgeBlock = *PI++;
    }
    assert(PI == Header->pred_end() && "Loop headers should have 2 preds!");

    // Add incoming values for the PHI node...
    PN->addIncoming(Constant::getNullConstant(Type::UIntTy), Incoming);
    PN->addIncoming(Add, BackEdgeBlock);

    // Analyze the new induction variable...
    IndVars.push_back(InductionVariable(PN, Loops));
    assert(IndVars.back().InductionType == InductionVariable::Cannonical &&
           "Just inserted cannonical indvar that is not cannonical!");
    Cannonical = &IndVars.back();
  }

#ifdef DEBUG
  cerr << "Induction variables:\n";
#endif

  // Get the current loop iteration count, which is always the value of the
  // cannonical phi node...
  //
  PHINode *IterCount = Cannonical->Phi;

  // Loop through and replace all of the auxillary induction variables with
  // references to the primary induction variable...
  //
  unsigned InsertPos = IndVars.size();
  for (unsigned i = 0; i < IndVars.size(); ++i) {
    InductionVariable *IV = &IndVars[i];
#ifdef DEBUG
    cerr << IndVars[i];
#endif
    if (IV != Cannonical) {  // Don't modify the cannonical indvar
      Instruction *Val = IterCount;
      if (!isa<ConstantInt>(IV->Step) ||   // If the step != 1
          !cast<ConstantInt>(IV->Step)->equalsInt(1)) {
        string Name;   // Create a scale by the step value...
        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-scale";

        // If the types are not compatible, insert a cast now...
        if (Val->getType() != IV->Step->getType())
          Val = InsertCast(Val, IV->Step->getType(),
                           Header->begin()+InsertPos++);

        Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step, Name);
        // Insert the phi node at the end of the other phi nodes...
        Header->getInstList().insert(Header->begin()+InsertPos++, Val);
      }

      if (!isa<Constant>(IV->Start) ||   // If the start != 0
          !cast<Constant>(IV->Start)->isNullValue()) {
        string Name;   // Create a offset by the start value...
        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-offset";

        // If the types are not compatible, insert a cast now...
        if (Val->getType() != IV->Start->getType())
          Val = InsertCast(Val, IV->Start->getType(),
                           Header->begin()+InsertPos++);

        Val = BinaryOperator::create(Instruction::Add, Val, IV->Start, Name);
        // Insert the phi node at the end of the other phi nodes...
        Header->getInstList().insert(Header->begin()+InsertPos++, Val);
      }

      // If the PHI node has a different type than val is, insert a cast now...
      if (Val->getType() != IV->Phi->getType())
          Val = InsertCast(Val, IV->Phi->getType(),
                           Header->begin()+InsertPos++);

      // Replace all uses of the old PHI node with the new computed value...
      IV->Phi->replaceAllUsesWith(Val);

      // Move the PHI name to it's new equivalent value...
      string OldName = IV->Phi->getName();
      IV->Phi->setName("");
      Val->setName(OldName);

      // Delete the old, now unused, phi node...
      Header->getInstList().remove(IV->Phi);
      delete IV->Phi;
      InsertPos--;            // Deleted an instr, decrement insert position
    }
  }

  return Changed;
}

bool InductionVariableSimplify::doit(Method *M) {
  // Figure out the loop structure of the method...
  cfg::LoopInfo Loops(M);

  // Induction Variables live in the header nodes of the loops of the method...
  return reduce_apply_bool(Loops.getTopLevelLoops().begin(),
                           Loops.getTopLevelLoops().end(),
                           std::bind1st(std::ptr_fun(TransformLoop), &Loops));
}
<commit_msg>Fix bugs, don't do external methods which causes segv.<commit_after>//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
//
// InductionVariableSimplify - Transform induction variables in a program
//   to all use a single cannonical induction variable per loop.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Analysis/InductionVariable.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/Type.h"
#include "llvm/ConstantVals.h"
#include "Support/STLExtras.h"

#if 0
#define DEBUG
#include "llvm/Analysis/Writer.h"
#endif

// InsertCast - Cast Val to Ty, setting a useful name on the cast if Val has a
// name...
//
static Instruction *InsertCast(Instruction *Val, const Type *Ty,
                               BasicBlock::iterator It) {
  Instruction *Cast = new CastInst(Val, Ty);
  if (Val->hasName()) Cast->setName(Val->getName()+"-casted");
  Val->getParent()->getInstList().insert(It, Cast);
  return Cast;
}

static bool TransformLoop(cfg::LoopInfo *Loops, cfg::Loop *Loop) {
  // Transform all subloops before this loop...
  bool Changed = reduce_apply_bool(Loop->getSubLoops().begin(),
                                   Loop->getSubLoops().end(),
                                   std::bind1st(ptr_fun(TransformLoop), Loops));
  // Get the header node for this loop.  All of the phi nodes that could be
  // induction variables must live in this basic block.
  BasicBlock *Header = (BasicBlock*)Loop->getBlocks().front();

  // Loop over all of the PHI nodes in the basic block, calculating the
  // induction variables that they represent... stuffing the induction variable
  // info into a vector...
  //
  vector<InductionVariable> IndVars;    // Induction variables for block
  for (BasicBlock::iterator I = Header->begin();
       PHINode *PN = dyn_cast<PHINode>(*I); ++I)
    IndVars.push_back(InductionVariable(PN, Loops));

  // If there are no phi nodes in this basic block, there can't be indvars...
  if (IndVars.empty()) return Changed;

  // Loop over the induction variables, looking for a cannonical induction
  // variable, and checking to make sure they are not all unknown induction
  // variables.
  //
  bool FoundIndVars = false;
  InductionVariable *Cannonical = 0;
  for (unsigned i = 0; i < IndVars.size(); ++i) {
    if (IndVars[i].InductionType == InductionVariable::Cannonical)
      Cannonical = &IndVars[i];
    if (IndVars[i].InductionType != InductionVariable::Unknown)
      FoundIndVars = true;
  }

  // No induction variables, bail early... don't add a cannonnical indvar
  if (!FoundIndVars) return Changed;

  // Okay, we want to convert other induction variables to use a cannonical
  // indvar.  If we don't have one, add one now...
  if (!Cannonical) {
    // Create the PHI node for the new induction variable
    PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar");

    // Insert the phi node at the end of the other phi nodes...
    Header->getInstList().insert(Header->begin()+IndVars.size(), PN);

    // Create the increment instruction to add one to the counter...
    Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
                                              ConstantUInt::get(Type::UIntTy,1),
                                              "add1-indvar");

    // Insert the add instruction after all of the PHI nodes...
    Header->getInstList().insert(Header->begin()+(IndVars.size()+1), Add);

    // Figure out which block is incoming and which is the backedge for the loop
    BasicBlock *Incoming, *BackEdgeBlock;
    BasicBlock::pred_iterator PI = Header->pred_begin();
    assert(PI != Header->pred_end() && "Loop headers should have 2 preds!");
    if (Loop->contains(*PI)) {  // First pred is back edge...
      BackEdgeBlock = *PI++;
      Incoming      = *PI++;
    } else {
      Incoming      = *PI++;
      BackEdgeBlock = *PI++;
    }
    assert(PI == Header->pred_end() && "Loop headers should have 2 preds!");

    // Add incoming values for the PHI node...
    PN->addIncoming(Constant::getNullConstant(Type::UIntTy), Incoming);
    PN->addIncoming(Add, BackEdgeBlock);

    // Analyze the new induction variable...
    IndVars.push_back(InductionVariable(PN, Loops));
    assert(IndVars.back().InductionType == InductionVariable::Cannonical &&
           "Just inserted cannonical indvar that is not cannonical!");
    Cannonical = &IndVars.back();
  }

#ifdef DEBUG
  cerr << "Induction variables:\n";
#endif

  // Get the current loop iteration count, which is always the value of the
  // cannonical phi node...
  //
  PHINode *IterCount = Cannonical->Phi;

  // Loop through and replace all of the auxillary induction variables with
  // references to the primary induction variable...
  //
  unsigned InsertPos = IndVars.size();
  for (unsigned i = 0; i < IndVars.size(); ++i) {
    InductionVariable *IV = &IndVars[i];
#ifdef DEBUG
    cerr << IndVars[i];
#endif
    // Don't modify the cannonical indvar or unrecognized indvars...
    if (IV != Cannonical && IV->InductionType != InductionVariable::Unknown) {
      Instruction *Val = IterCount;
      if (!isa<ConstantInt>(IV->Step) ||   // If the step != 1
          !cast<ConstantInt>(IV->Step)->equalsInt(1)) {
        string Name;   // Create a scale by the step value...
        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-scale";

        // If the types are not compatible, insert a cast now...
        if (Val->getType() != IV->Step->getType())
          Val = InsertCast(Val, IV->Step->getType(),
                           Header->begin()+InsertPos++);

        Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step, Name);
        // Insert the phi node at the end of the other phi nodes...
        Header->getInstList().insert(Header->begin()+InsertPos++, Val);
      }

      if (!isa<Constant>(IV->Start) ||   // If the start != 0
          !cast<Constant>(IV->Start)->isNullValue()) {
        string Name;   // Create a offset by the start value...
        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-offset";

        // If the types are not compatible, insert a cast now...
        if (Val->getType() != IV->Start->getType())
          Val = InsertCast(Val, IV->Start->getType(),
                           Header->begin()+InsertPos++);

        Val = BinaryOperator::create(Instruction::Add, Val, IV->Start, Name);
        // Insert the phi node at the end of the other phi nodes...
        Header->getInstList().insert(Header->begin()+InsertPos++, Val);
      }

      // If the PHI node has a different type than val is, insert a cast now...
      if (Val->getType() != IV->Phi->getType())
          Val = InsertCast(Val, IV->Phi->getType(),
                           Header->begin()+InsertPos++);

      // Replace all uses of the old PHI node with the new computed value...
      IV->Phi->replaceAllUsesWith(Val);

      // Move the PHI name to it's new equivalent value...
      string OldName = IV->Phi->getName();
      IV->Phi->setName("");
      Val->setName(OldName);

      // Delete the old, now unused, phi node...
      Header->getInstList().remove(IV->Phi);
      delete IV->Phi;
      InsertPos--;            // Deleted an instr, decrement insert position
    }
  }

  return Changed;
}

bool InductionVariableSimplify::doit(Method *M) {
  if (M->isExternal()) return false;

  // Figure out the loop structure of the method...
  cfg::LoopInfo Loops(M);

  // Induction Variables live in the header nodes of the loops of the method...
  return reduce_apply_bool(Loops.getTopLevelLoops().begin(),
                           Loops.getTopLevelLoops().end(),
                           std::bind1st(std::ptr_fun(TransformLoop), &Loops));
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <sal/config.h>

#include <memory>

#include <sfx2/request.hxx>
#include <svl/eitem.hxx>
#include <basic/sbxvar.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>

#include <view.hxx>
#include <wrtsh.hxx>
#include <textsh.hxx>
#include <num.hxx>
#include <edtwin.hxx>
#include <crsskip.hxx>
#include <doc.hxx>
#include <docsh.hxx>

#include <cmdid.h>
#include <globals.h>
#include <globals.hrc>

#include <svx/svdouno.hxx>
#include <svx/fmshell.hxx>
#include <svx/sdrobjectfilter.hxx>

using namespace ::com::sun::star;

void SwTextShell::ExecBasicMove(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();
    const SfxItemSet *pArgs = rReq.GetArgs();
    bool bSelect = false;
    sal_Int32 nCount = 1;
    if(pArgs)
    {
        const SfxPoolItem *pItem;
        if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_COUNT, true, &pItem))
            nCount = static_cast<const SfxInt32Item *>(pItem)->GetValue();
        if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_SELECTION, true, &pItem))
            bSelect = static_cast<const SfxBoolItem *>(pItem)->GetValue();
    }
    switch(rReq.GetSlot())
    {
        case FN_CHAR_LEFT_SEL:
            rReq.SetSlot( FN_CHAR_LEFT );
            bSelect = true;
            break;
        case FN_CHAR_RIGHT_SEL:
            rReq.SetSlot( FN_CHAR_RIGHT );
            bSelect = true;
            break;
        case FN_LINE_UP_SEL:
            rReq.SetSlot( FN_LINE_UP );
            bSelect = true;
            break;
        case FN_LINE_DOWN_SEL:
            rReq.SetSlot( FN_LINE_DOWN );
            bSelect = true;
            break;
    }

    uno::Reference< frame::XDispatchRecorder > xRecorder =
            GetView().GetViewFrame()->GetBindings().GetRecorder();
    if ( xRecorder.is() )
    {
        rReq.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nCount) );
        rReq.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, bSelect) );
    }
    const sal_uInt16 nSlot = rReq.GetSlot();
    rReq.Done();
    // Get EditWin before calling the move functions (shell change may occur!)
    SwEditWin& rTmpEditWin = GetView().GetEditWin();
    for( sal_Int32 i = 0; i < nCount; i++ )
    {
        switch(nSlot)
        {
            case FN_CHAR_LEFT:
                rSh.Left( CRSR_SKIP_CELLS,  bSelect, 1, false, true );
                break;
            case FN_CHAR_RIGHT:
                rSh.Right( CRSR_SKIP_CELLS, bSelect, 1, false, true );
                break;
            case FN_LINE_UP:
                rSh.Up( bSelect, 1 );
                break;
            case FN_LINE_DOWN:
                rSh.Down( bSelect, 1 );
                break;
            default:
                OSL_FAIL("wrong Dispatcher");
                return;
        }
    }

    //#i42732# - notify the edit window that from now on we do not use the input language
    rTmpEditWin.SetUseInputLanguage( false );
}

void SwTextShell::ExecMove(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    SwEditWin& rTmpEditWin = GetView().GetEditWin();
    rTmpEditWin.FlushInBuffer();

    bool bRet = false;
    switch ( rReq.GetSlot() )
    {
        case FN_START_OF_LINE_SEL:
            bRet = rSh.LeftMargin( true, false );
            break;
        case FN_START_OF_LINE:
            bRet = rSh.LeftMargin( false, false );
            break;
        case FN_END_OF_LINE_SEL:
            bRet = rSh.RightMargin( true, false );
            break;
        case FN_END_OF_LINE:
            bRet = rSh.RightMargin( false, false );
            break;
        case FN_START_OF_DOCUMENT_SEL:
            bRet = rSh.SttDoc( true );
            break;
        case FN_START_OF_DOCUMENT:
            bRet = rSh.SttDoc( false );
            break;
        case FN_END_OF_DOCUMENT_SEL:
            bRet = rSh.EndDoc( true );
            break;
        case FN_END_OF_DOCUMENT:
            bRet = rSh.EndDoc( false );
            break;
        case FN_SELECT_WORD:
            bRet = rSh.SelNearestWrd();
            break;
        case SID_SELECTALL:
            bRet = 0 != rSh.SelAll();
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }

    if ( bRet )
        rReq.Done();
    else
        rReq.Ignore();

    //#i42732# - notify the edit window that from now on we do not use the input language
    rTmpEditWin.SetUseInputLanguage( false );
}

void SwTextShell::ExecMovePage(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();

    switch( rReq.GetSlot() )
    {
        case FN_START_OF_NEXT_PAGE_SEL :
            rSh.SttNxtPg( true );
            break;
        case FN_START_OF_NEXT_PAGE:
            rSh.SttNxtPg( false );
            break;
        case FN_END_OF_NEXT_PAGE_SEL:
            rSh.EndNxtPg( true );
            break;
        case FN_END_OF_NEXT_PAGE:
            rSh.EndNxtPg( false );
            break;
        case FN_START_OF_PREV_PAGE_SEL:
            rSh.SttPrvPg( true );
            break;
        case FN_START_OF_PREV_PAGE:
            rSh.SttPrvPg( false );
            break;
        case FN_END_OF_PREV_PAGE_SEL:
            rSh.EndPrvPg( true );
            break;
        case FN_END_OF_PREV_PAGE:
            rSh.EndPrvPg( false );
            break;
        case FN_START_OF_PAGE_SEL:
            rSh.SttPg( true );
            break;
        case FN_START_OF_PAGE:
            rSh.SttPg( false );
            break;
        case FN_END_OF_PAGE_SEL:
            rSh.EndPg( true );
            break;
        case FN_END_OF_PAGE:
            rSh.EndPg( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveCol(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    switch ( rReq.GetSlot() )
    {
        case FN_START_OF_COLUMN:
            rSh.StartOfColumn( false );
            break;
        case FN_END_OF_COLUMN:
            rSh.EndOfColumn( false );
            break;
        case FN_START_OF_NEXT_COLUMN:
            rSh.StartOfNextColumn( false ) ;
            break;
        case FN_END_OF_NEXT_COLUMN:
            rSh.EndOfNextColumn( false );
            break;
        case FN_START_OF_PREV_COLUMN:
            rSh.StartOfPrevColumn( false );
            break;
        case FN_END_OF_PREV_COLUMN:
            rSh.EndOfPrevColumn( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveLingu(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();

    switch ( rReq.GetSlot() )
    {
        case FN_NEXT_WORD_SEL:
            rSh.NxtWrd( true );
            break;
        case FN_NEXT_WORD:
            rSh.NxtWrd( false );
            break;
        case FN_START_OF_PARA_SEL:
            rSh.SttPara( true );
            break;
        case FN_START_OF_PARA:
            rSh.SttPara( false );
            break;
        case FN_END_OF_PARA_SEL:
            rSh.EndPara( true );
            break;
        case FN_END_OF_PARA:
            rSh.EndPara( false );
            break;
        case FN_PREV_WORD_SEL:
            rSh.PrvWrd( true );
            break;
        case FN_PREV_WORD:
            rSh.PrvWrd( false );
            break;
        case FN_NEXT_SENT_SEL:
            rSh.FwdSentence( true );
            break;
        case FN_NEXT_SENT:
            rSh.FwdSentence( false );
            break;
        case FN_PREV_SENT_SEL:
            rSh.BwdSentence( true );
            break;
        case FN_PREV_SENT:
            rSh.BwdSentence( false );
            break;
        case FN_NEXT_PARA:
            rSh.FwdPara( false );
            break;
        case FN_PREV_PARA:
            rSh.BwdPara( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveMisc(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    const sal_uInt16 nSlot = rReq.GetSlot();
    bool bSetRetVal = true, bRet = true;
    switch ( nSlot )
    {
        case SID_FM_TOGGLECONTROLFOCUS:
            {
                const SwDoc* pDoc = rSh.GetDoc();
                const SwDocShell* pDocShell = pDoc ? pDoc->GetDocShell() : NULL;
                const SwView* pView = pDocShell ? pDocShell->GetView() : NULL;
                const FmFormShell* pFormShell = pView ? pView->GetFormShell() : NULL;
                SdrView* pDrawView = pView ? pView->GetDrawView() : NULL;
                vcl::Window* pWindow = pView ? pView->GetWrtShell().GetWin() : NULL;

                OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::ExecMoveMisc: no chance!" );
                if ( !pFormShell || !pDrawView || !pWindow )
                    break;

                std::unique_ptr< ::svx::ISdrObjectFilter > pFilter( pFormShell->CreateFocusableControlFilter(
                    *pDrawView, *pWindow ) );
                if ( !pFilter.get() )
                    break;

                const SdrObject* pNearestControl = rSh.GetBestObject( true, GOTOOBJ_DRAW_CONTROL, false, pFilter.get() );
                if ( !pNearestControl )
                    break;

                const SdrUnoObj* pUnoObject = dynamic_cast< const SdrUnoObj* >( pNearestControl );
                OSL_ENSURE( pUnoObject, "SwTextShell::ExecMoveMisc: GetBestObject returned nonsense!" );
                if ( !pUnoObject )
                    break;

                pFormShell->ToggleControlFocus( *pUnoObject, *pDrawView, *pWindow );
            }
            break;
        case FN_CNTNT_TO_NEXT_FRAME:
            bRet = rSh.GotoObj(true, GOTOOBJ_GOTO_ANY);
            if(bRet)
            {
                rSh.HideCrsr();
                rSh.EnterSelFrmMode();
            }
        break;
        case FN_NEXT_FOOTNOTE:
            rSh.MoveCrsr();
            bRet = rSh.GotoNextFtnAnchor();
            break;
        case FN_PREV_FOOTNOTE:
            rSh.MoveCrsr();
            bRet = rSh.GotoPrevFtnAnchor();
            break;
        case FN_TO_HEADER:
            rSh.MoveCrsr();
            if ( ( FRMTYPE_HEADER & rSh.GetFrmType(0,false) ) || rSh.GotoHeaderTxt() )
                rSh.SttPg();
            bSetRetVal = false;
            break;
        case FN_TO_FOOTER:
            rSh.MoveCrsr();
            if ( ( FRMTYPE_FOOTER & rSh.GetFrmType(0,false) ) || rSh.GotoFooterTxt() )
                rSh.EndPg();
            bSetRetVal = false;
            break;
        case FN_FOOTNOTE_TO_ANCHOR:
            rSh.MoveCrsr();
            if ( FRMTYPE_FOOTNOTE & rSh.GetFrmType(0,false) )
                rSh.GotoFtnAnchor();
            else
                rSh.GotoFtnTxt();
            bSetRetVal = false;
            break;
        case FN_TO_FOOTNOTE_AREA :
            rSh.GotoFtnTxt();
            break;
        case FN_PREV_TABLE:
            bRet = rSh.MoveTable( fnTablePrev, fnTableStart);
            break;
        case FN_NEXT_TABLE:
            bRet = rSh.MoveTable(fnTableNext, fnTableStart);
            break;
        case FN_GOTO_NEXT_REGION :
            bRet = rSh.MoveRegion(fnRegionNext, fnRegionStart);
            break;
        case FN_GOTO_PREV_REGION :
            bRet = rSh.MoveRegion(fnRegionPrev, fnRegionStart);
            break;
        case FN_NEXT_TOXMARK:
            bRet = rSh.GotoNxtPrvTOXMark( true );
            break;
        case FN_PREV_TOXMARK:
            bRet = rSh.GotoNxtPrvTOXMark( false );
            break;
        case FN_NEXT_TBLFML:
            bRet = rSh.GotoNxtPrvTblFormula( true, false );
            break;
        case FN_PREV_TBLFML:
            bRet = rSh.GotoNxtPrvTblFormula( false, false );
            break;
        case FN_NEXT_TBLFML_ERR:
            bRet = rSh.GotoNxtPrvTblFormula( true, true );
            break;
        case FN_PREV_TBLFML_ERR:
            bRet = rSh.GotoNxtPrvTblFormula( false, true );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }

    if( bSetRetVal )
        rReq.SetReturnValue(SfxBoolItem( nSlot, bRet ));
    rReq.Done();

    bool bInHeader = true;
    if ( rSh.IsInHeaderFooter( &bInHeader ) )
    {
        if ( !bInHeader )
        {
            rSh.SetShowHeaderFooterSeparator( Footer, true );
            rSh.SetShowHeaderFooterSeparator( Header, false );
        }
        else
        {
            rSh.SetShowHeaderFooterSeparator( Header, true );
            rSh.SetShowHeaderFooterSeparator( Footer, false );
        }

        // Force repaint
        rSh.GetWin()->Invalidate();
    }
    if ( rSh.IsInHeaderFooter() != rSh.IsHeaderFooterEdit() )
        rSh.ToggleHeaderFooterEdit();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fdo#82614: sw: Revert "Simplify code path"<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <sal/config.h>

#include <memory>

#include <sfx2/request.hxx>
#include <svl/eitem.hxx>
#include <basic/sbxvar.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>

#include <view.hxx>
#include <wrtsh.hxx>
#include <textsh.hxx>
#include <num.hxx>
#include <edtwin.hxx>
#include <crsskip.hxx>
#include <doc.hxx>
#include <docsh.hxx>

#include <cmdid.h>
#include <globals.h>
#include <globals.hrc>

#include <svx/svdouno.hxx>
#include <svx/fmshell.hxx>
#include <svx/sdrobjectfilter.hxx>

using namespace ::com::sun::star;

void SwTextShell::ExecBasicMove(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();
    const SfxItemSet *pArgs = rReq.GetArgs();
    bool bSelect = false;
    sal_Int32 nCount = 1;
    if(pArgs)
    {
        const SfxPoolItem *pItem;
        if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_COUNT, true, &pItem))
            nCount = static_cast<const SfxInt32Item *>(pItem)->GetValue();
        if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_SELECTION, true, &pItem))
            bSelect = static_cast<const SfxBoolItem *>(pItem)->GetValue();
    }
    switch(rReq.GetSlot())
    {
        case FN_CHAR_LEFT_SEL:
            rReq.SetSlot( FN_CHAR_LEFT );
            bSelect = true;
            break;
        case FN_CHAR_RIGHT_SEL:
            rReq.SetSlot( FN_CHAR_RIGHT );
            bSelect = true;
            break;
        case FN_LINE_UP_SEL:
            rReq.SetSlot( FN_LINE_UP );
            bSelect = true;
            break;
        case FN_LINE_DOWN_SEL:
            rReq.SetSlot( FN_LINE_DOWN );
            bSelect = true;
            break;
    }

    uno::Reference< frame::XDispatchRecorder > xRecorder =
            GetView().GetViewFrame()->GetBindings().GetRecorder();
    if ( xRecorder.is() )
    {
        rReq.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nCount) );
        rReq.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, bSelect) );
    }
    const sal_uInt16 nSlot = rReq.GetSlot();
    rReq.Done();
    // Get EditWin before calling the move functions (shell change may occur!)
    SwEditWin& rTmpEditWin = GetView().GetEditWin();
    for( sal_Int32 i = 0; i < nCount; i++ )
    {
        switch(nSlot)
        {
            case FN_CHAR_LEFT:
                rSh.Left( CRSR_SKIP_CELLS,  bSelect, 1, false, true );
                break;
            case FN_CHAR_RIGHT:
                rSh.Right( CRSR_SKIP_CELLS, bSelect, 1, false, true );
                break;
            case FN_LINE_UP:
                rSh.Up( bSelect, 1 );
                break;
            case FN_LINE_DOWN:
                rSh.Down( bSelect, 1 );
                break;
            default:
                OSL_FAIL("wrong Dispatcher");
                return;
        }
    }

    //#i42732# - notify the edit window that from now on we do not use the input language
    rTmpEditWin.SetUseInputLanguage( false );
}

void SwTextShell::ExecMove(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    SwEditWin& rTmpEditWin = GetView().GetEditWin();
    rTmpEditWin.FlushInBuffer();

    bool bRet = false;
    switch ( rReq.GetSlot() )
    {
        case FN_START_OF_LINE_SEL:
            bRet = rSh.LeftMargin( true, false );
            break;
        case FN_START_OF_LINE:
            bRet = rSh.LeftMargin( false, false );
            break;
        case FN_END_OF_LINE_SEL:
            bRet = rSh.RightMargin( true, false );
            break;
        case FN_END_OF_LINE:
            bRet = rSh.RightMargin( false, false );
            break;
        case FN_START_OF_DOCUMENT_SEL:
            bRet = rSh.SttDoc( true );
            break;
        case FN_START_OF_DOCUMENT:
            bRet = rSh.SttDoc( false );
            break;
        case FN_END_OF_DOCUMENT_SEL:
            bRet = rSh.EndDoc( true );
            break;
        case FN_END_OF_DOCUMENT:
            bRet = rSh.EndDoc( false );
            break;
        case FN_SELECT_WORD:
            bRet = rSh.SelNearestWrd();
            break;
        case SID_SELECTALL:
            bRet = 0 != rSh.SelAll();
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }

    if ( bRet )
        rReq.Done();
    else
        rReq.Ignore();

    //#i42732# - notify the edit window that from now on we do not use the input language
    rTmpEditWin.SetUseInputLanguage( false );
}

void SwTextShell::ExecMovePage(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();

    switch( rReq.GetSlot() )
    {
        case FN_START_OF_NEXT_PAGE_SEL :
            rSh.SttNxtPg( true );
            break;
        case FN_START_OF_NEXT_PAGE:
            rSh.SttNxtPg( false );
            break;
        case FN_END_OF_NEXT_PAGE_SEL:
            rSh.EndNxtPg( true );
            break;
        case FN_END_OF_NEXT_PAGE:
            rSh.EndNxtPg( false );
            break;
        case FN_START_OF_PREV_PAGE_SEL:
            rSh.SttPrvPg( true );
            break;
        case FN_START_OF_PREV_PAGE:
            rSh.SttPrvPg( false );
            break;
        case FN_END_OF_PREV_PAGE_SEL:
            rSh.EndPrvPg( true );
            break;
        case FN_END_OF_PREV_PAGE:
            rSh.EndPrvPg( false );
            break;
        case FN_START_OF_PAGE_SEL:
            rSh.SttPg( true );
            break;
        case FN_START_OF_PAGE:
            rSh.SttPg( false );
            break;
        case FN_END_OF_PAGE_SEL:
            rSh.EndPg( true );
            break;
        case FN_END_OF_PAGE:
            rSh.EndPg( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveCol(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    switch ( rReq.GetSlot() )
    {
        case FN_START_OF_COLUMN:
            rSh.StartOfColumn( false );
            break;
        case FN_END_OF_COLUMN:
            rSh.EndOfColumn( false );
            break;
        case FN_START_OF_NEXT_COLUMN:
            rSh.StartOfNextColumn( false ) ;
            break;
        case FN_END_OF_NEXT_COLUMN:
            rSh.EndOfNextColumn( false );
            break;
        case FN_START_OF_PREV_COLUMN:
            rSh.StartOfPrevColumn( false );
            break;
        case FN_END_OF_PREV_COLUMN:
            rSh.EndOfPrevColumn( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveLingu(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    GetView().GetEditWin().FlushInBuffer();

    switch ( rReq.GetSlot() )
    {
        case FN_NEXT_WORD_SEL:
            rSh.NxtWrd( true );
            break;
        case FN_NEXT_WORD:
            rSh.NxtWrd( false );
            break;
        case FN_START_OF_PARA_SEL:
            rSh.SttPara( true );
            break;
        case FN_START_OF_PARA:
            rSh.SttPara( false );
            break;
        case FN_END_OF_PARA_SEL:
            rSh.EndPara( true );
            break;
        case FN_END_OF_PARA:
            rSh.EndPara( false );
            break;
        case FN_PREV_WORD_SEL:
            rSh.PrvWrd( true );
            break;
        case FN_PREV_WORD:
            rSh.PrvWrd( false );
            break;
        case FN_NEXT_SENT_SEL:
            rSh.FwdSentence( true );
            break;
        case FN_NEXT_SENT:
            rSh.FwdSentence( false );
            break;
        case FN_PREV_SENT_SEL:
            rSh.BwdSentence( true );
            break;
        case FN_PREV_SENT:
            rSh.BwdSentence( false );
            break;
        case FN_NEXT_PARA:
            rSh.FwdPara( false );
            break;
        case FN_PREV_PARA:
            rSh.BwdPara( false );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }
    rReq.Done();
}

void SwTextShell::ExecMoveMisc(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    const sal_uInt16 nSlot = rReq.GetSlot();
    bool bSetRetVal = true, bRet = true;
    switch ( nSlot )
    {
        case SID_FM_TOGGLECONTROLFOCUS:
            {
                const SwDoc* pDoc = rSh.GetDoc();
                const SwDocShell* pDocShell = pDoc ? pDoc->GetDocShell() : NULL;
                const SwView* pView = pDocShell ? pDocShell->GetView() : NULL;
                const FmFormShell* pFormShell = pView ? pView->GetFormShell() : NULL;
                SdrView* pDrawView = pView ? pView->GetDrawView() : NULL;
                vcl::Window* pWindow = pView ? pView->GetWrtShell().GetWin() : NULL;

                OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::ExecMoveMisc: no chance!" );
                if ( !pFormShell || !pDrawView || !pWindow )
                    break;

                std::unique_ptr< ::svx::ISdrObjectFilter > pFilter( pFormShell->CreateFocusableControlFilter(
                    *pDrawView, *pWindow ) );
                if ( !pFilter.get() )
                    break;

                const SdrObject* pNearestControl = rSh.GetBestObject( true, GOTOOBJ_DRAW_CONTROL, false, pFilter.get() );
                if ( !pNearestControl )
                    break;

                const SdrUnoObj* pUnoObject = dynamic_cast< const SdrUnoObj* >( pNearestControl );
                OSL_ENSURE( pUnoObject, "SwTextShell::ExecMoveMisc: GetBestObject returned nonsense!" );
                if ( !pUnoObject )
                    break;

                pFormShell->ToggleControlFocus( *pUnoObject, *pDrawView, *pWindow );
            }
            break;
        case FN_CNTNT_TO_NEXT_FRAME:
            bRet = rSh.GotoObj(true, GOTOOBJ_GOTO_ANY);
            if(bRet)
            {
                rSh.HideCrsr();
                rSh.EnterSelFrmMode();
            }
        break;
        case FN_NEXT_FOOTNOTE:
            rSh.MoveCrsr();
            bRet = rSh.GotoNextFtnAnchor();
            break;
        case FN_PREV_FOOTNOTE:
            rSh.MoveCrsr();
            bRet = rSh.GotoPrevFtnAnchor();
            break;
        case FN_TO_HEADER:
            rSh.MoveCrsr();
            if ( FRMTYPE_HEADER & rSh.GetFrmType(0,false) )
                rSh.SttPg();
            else
            {
                bool bMoved = rSh.GotoHeaderTxt();
                if ( !bMoved )
                    rSh.SttPg();
            }
            bSetRetVal = false;
            break;
        case FN_TO_FOOTER:
            rSh.MoveCrsr();
            if ( FRMTYPE_FOOTER & rSh.GetFrmType(0,false) )
                rSh.EndPg();
            else
            {
                bool bMoved = rSh.GotoFooterTxt();
                if ( !bMoved )
                    rSh.EndPg();
            }
            bSetRetVal = false;
            break;
        case FN_FOOTNOTE_TO_ANCHOR:
            rSh.MoveCrsr();
            if ( FRMTYPE_FOOTNOTE & rSh.GetFrmType(0,false) )
                rSh.GotoFtnAnchor();
            else
                rSh.GotoFtnTxt();
            bSetRetVal = false;
            break;
        case FN_TO_FOOTNOTE_AREA :
            rSh.GotoFtnTxt();
            break;
        case FN_PREV_TABLE:
            bRet = rSh.MoveTable( fnTablePrev, fnTableStart);
            break;
        case FN_NEXT_TABLE:
            bRet = rSh.MoveTable(fnTableNext, fnTableStart);
            break;
        case FN_GOTO_NEXT_REGION :
            bRet = rSh.MoveRegion(fnRegionNext, fnRegionStart);
            break;
        case FN_GOTO_PREV_REGION :
            bRet = rSh.MoveRegion(fnRegionPrev, fnRegionStart);
            break;
        case FN_NEXT_TOXMARK:
            bRet = rSh.GotoNxtPrvTOXMark( true );
            break;
        case FN_PREV_TOXMARK:
            bRet = rSh.GotoNxtPrvTOXMark( false );
            break;
        case FN_NEXT_TBLFML:
            bRet = rSh.GotoNxtPrvTblFormula( true, false );
            break;
        case FN_PREV_TBLFML:
            bRet = rSh.GotoNxtPrvTblFormula( false, false );
            break;
        case FN_NEXT_TBLFML_ERR:
            bRet = rSh.GotoNxtPrvTblFormula( true, true );
            break;
        case FN_PREV_TBLFML_ERR:
            bRet = rSh.GotoNxtPrvTblFormula( false, true );
            break;
        default:
            OSL_FAIL("wrong dispatcher");
            return;
    }

    if( bSetRetVal )
        rReq.SetReturnValue(SfxBoolItem( nSlot, bRet ));
    rReq.Done();

    bool bInHeader = true;
    if ( rSh.IsInHeaderFooter( &bInHeader ) )
    {
        if ( !bInHeader )
        {
            rSh.SetShowHeaderFooterSeparator( Footer, true );
            rSh.SetShowHeaderFooterSeparator( Header, false );
        }
        else
        {
            rSh.SetShowHeaderFooterSeparator( Header, true );
            rSh.SetShowHeaderFooterSeparator( Footer, false );
        }

        // Force repaint
        rSh.GetWin()->Invalidate();
    }
    if ( rSh.IsInHeaderFooter() != rSh.IsHeaderFooterEdit() )
        rSh.ToggleHeaderFooterEdit();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements a simple loop unroller.  It works best when loops have
// been canonicalized by the -indvars pass, allowing it to determine the trip
// counts of loops easily.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-unroll"
#include "llvm/IntrinsicInst.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
#include <climits>

using namespace llvm;

static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::init(150), cl::Hidden,
  cl::desc("The cut-off point for automatic loop unrolling"));

static cl::opt<unsigned>
UnrollCount("unroll-count", cl::init(0), cl::Hidden,
  cl::desc("Use this unroll count for all loops, for testing purposes"));

static cl::opt<bool>
UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
  cl::desc("Allows loops to be partially unrolled until "
           "-unroll-threshold loop size is reached."));

namespace {
  class LoopUnroll : public LoopPass {
  public:
    static char ID; // Pass ID, replacement for typeid
    LoopUnroll() : LoopPass(ID) {}

    /// A magic value for use with the Threshold parameter to indicate
    /// that the loop unroll should be performed regardless of how much
    /// code expansion would result.
    static const unsigned NoThreshold = UINT_MAX;

    // Threshold to use when optsize is specified (and there is no
    // explicit -unroll-threshold).
    static const unsigned OptSizeUnrollThreshold = 50;

    unsigned CurrentThreshold;

    bool runOnLoop(Loop *L, LPPassManager &LPM);

    /// This transformation requires natural loop information & requires that
    /// loop preheaders be inserted into the CFG...
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LoopInfo>();
      AU.addPreserved<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LoopSimplifyID);
      AU.addRequiredID(LCSSAID);
      AU.addPreservedID(LCSSAID);
      AU.addPreserved<ScalarEvolution>();
      // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
      // If loop unroll does not preserve dom info then LCSSA pass on next
      // loop will receive invalid dom info.
      // For now, recreate dom info, if loop is unrolled.
      AU.addPreserved<DominatorTree>();
    }
  };
}

char LoopUnroll::ID = 0;
INITIALIZE_PASS(LoopUnroll, "loop-unroll", "Unroll loops", false, false);

Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }

/// ApproximateLoopSize - Approximate the size of the loop.
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
  CodeMetrics Metrics;
  for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
       I != E; ++I)
    Metrics.analyzeBasicBlock(*I);
  NumCalls = Metrics.NumInlineCandidates;

  unsigned LoopSize = Metrics.NumInsts;

  // If we can identify the induction variable, we know that it will become
  // constant when we unroll the loop, so factor that into our loop size
  // estimate.
  // FIXME: We have to divide by InlineConstants::InstrCost because the
  // measure returned by CountCodeReductionForConstant is not an instruction
  // count, but rather a weight as defined by InlineConstants.  It would
  // probably be a good idea to standardize on a single weighting scheme by
  // pushing more of the logic for weighting into CodeMetrics.
  if (PHINode *IndVar = L->getCanonicalInductionVariable()) {
    unsigned SizeDecrease = Metrics.CountCodeReductionForConstant(IndVar);
    // NOTE: Because SizeDecrease is a fuzzy estimate, we don't want to allow
    // it to totally negate the cost of unrolling a loop.
    SizeDecrease = SizeDecrease > LoopSize / 2 ? LoopSize / 2 : SizeDecrease;
  }

  // Don't allow an estimate of size zero.  This would allows unrolling of loops
  // with huge iteration counts, which is a compile time problem even if it's
  // not a problem for code quality.
  if (LoopSize == 0) LoopSize = 1;

  return LoopSize;
}

bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {

  LoopInfo *LI = &getAnalysis<LoopInfo>();

  BasicBlock *Header = L->getHeader();
  DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
        << "] Loop %" << Header->getName() << "\n");
  (void)Header;

  // Determine the current unrolling threshold.  While this is normally set
  // from UnrollThreshold, it is overridden to a smaller value if the current
  // function is marked as optimize-for-size, and the unroll threshold was
  // not user specified.
  CurrentThreshold = UnrollThreshold;
  if (Header->getParent()->hasFnAttr(Attribute::OptimizeForSize) &&
      UnrollThreshold.getNumOccurrences() == 0)
    CurrentThreshold = OptSizeUnrollThreshold;

  // Find trip count
  unsigned TripCount = L->getSmallConstantTripCount();
  unsigned Count = UnrollCount;

  // Automatically select an unroll count.
  if (Count == 0) {
    // Conservative heuristic: if we know the trip count, see if we can
    // completely unroll (subject to the threshold, checked below); otherwise
    // try to find greatest modulo of the trip count which is still under
    // threshold value.
    if (TripCount == 0)
      return false;
    Count = TripCount;
  }

  // Enforce the threshold.
  if (CurrentThreshold != NoThreshold) {
    unsigned NumInlineCandidates;
    unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates);
    DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
    if (NumInlineCandidates != 0) {
      DEBUG(dbgs() << "  Not unrolling loop with inlinable calls.\n");
      return false;
    }
    uint64_t Size = (uint64_t)LoopSize*Count;
    if (TripCount != 1 && Size > CurrentThreshold) {
      DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
            << " because size: " << Size << ">" << CurrentThreshold << "\n");
      if (!UnrollAllowPartial) {
        DEBUG(dbgs() << "  will not try to unroll partially because "
              << "-unroll-allow-partial not given\n");
        return false;
      }
      // Reduce unroll count to be modulo of TripCount for partial unrolling
      Count = CurrentThreshold / LoopSize;
      while (Count != 0 && TripCount%Count != 0) {
        Count--;
      }
      if (Count < 2) {
        DEBUG(dbgs() << "  could not unroll partially\n");
        return false;
      }
      DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
    }
  }

  // Unroll the loop.
  Function *F = L->getHeader()->getParent();
  if (!UnrollLoop(L, Count, LI, &LPM))
    return false;

  // FIXME: Reconstruct dom info, because it is not preserved properly.
  if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>())
    DT->runOnFunction(*F);
  return true;
}
<commit_msg>Weight loop unrolling counts by nesting depth. Unrolling deeply nested loops tends to cause high register pressure and thus excess spills, which we don't currently recover from well.  This should be re-evaluated in the future if our ability to generate good spills/splits improves.<commit_after>//===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements a simple loop unroller.  It works best when loops have
// been canonicalized by the -indvars pass, allowing it to determine the trip
// counts of loops easily.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-unroll"
#include "llvm/IntrinsicInst.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
#include <climits>

using namespace llvm;

static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::init(150), cl::Hidden,
  cl::desc("The cut-off point for automatic loop unrolling"));

static cl::opt<unsigned>
UnrollCount("unroll-count", cl::init(0), cl::Hidden,
  cl::desc("Use this unroll count for all loops, for testing purposes"));

static cl::opt<bool>
UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
  cl::desc("Allows loops to be partially unrolled until "
           "-unroll-threshold loop size is reached."));

namespace {
  class LoopUnroll : public LoopPass {
  public:
    static char ID; // Pass ID, replacement for typeid
    LoopUnroll() : LoopPass(ID) {}

    /// A magic value for use with the Threshold parameter to indicate
    /// that the loop unroll should be performed regardless of how much
    /// code expansion would result.
    static const unsigned NoThreshold = UINT_MAX;

    // Threshold to use when optsize is specified (and there is no
    // explicit -unroll-threshold).
    static const unsigned OptSizeUnrollThreshold = 50;

    unsigned CurrentThreshold;

    bool runOnLoop(Loop *L, LPPassManager &LPM);

    /// This transformation requires natural loop information & requires that
    /// loop preheaders be inserted into the CFG...
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LoopInfo>();
      AU.addPreserved<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LoopSimplifyID);
      AU.addRequiredID(LCSSAID);
      AU.addPreservedID(LCSSAID);
      AU.addPreserved<ScalarEvolution>();
      // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
      // If loop unroll does not preserve dom info then LCSSA pass on next
      // loop will receive invalid dom info.
      // For now, recreate dom info, if loop is unrolled.
      AU.addPreserved<DominatorTree>();
    }
  };
}

char LoopUnroll::ID = 0;
INITIALIZE_PASS(LoopUnroll, "loop-unroll", "Unroll loops", false, false);

Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }

/// ApproximateLoopSize - Approximate the size of the loop.
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
  CodeMetrics Metrics;
  for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
       I != E; ++I)
    Metrics.analyzeBasicBlock(*I);
  NumCalls = Metrics.NumInlineCandidates;

  unsigned LoopSize = Metrics.NumInsts;

  // If we can identify the induction variable, we know that it will become
  // constant when we unroll the loop, so factor that into our loop size
  // estimate.
  // FIXME: We have to divide by InlineConstants::InstrCost because the
  // measure returned by CountCodeReductionForConstant is not an instruction
  // count, but rather a weight as defined by InlineConstants.  It would
  // probably be a good idea to standardize on a single weighting scheme by
  // pushing more of the logic for weighting into CodeMetrics.
  if (PHINode *IndVar = L->getCanonicalInductionVariable()) {
    unsigned SizeDecrease = Metrics.CountCodeReductionForConstant(IndVar);
    // NOTE: Because SizeDecrease is a fuzzy estimate, we don't want to allow
    // it to totally negate the cost of unrolling a loop.
    SizeDecrease = SizeDecrease > LoopSize / 2 ? LoopSize / 2 : SizeDecrease;
  }

  // Don't allow an estimate of size zero.  This would allows unrolling of loops
  // with huge iteration counts, which is a compile time problem even if it's
  // not a problem for code quality.
  if (LoopSize == 0) LoopSize = 1;

  return LoopSize;
}

bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {

  LoopInfo *LI = &getAnalysis<LoopInfo>();

  BasicBlock *Header = L->getHeader();
  DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
        << "] Loop %" << Header->getName() << "\n");
  (void)Header;

  // Determine the current unrolling threshold.  While this is normally set
  // from UnrollThreshold, it is overridden to a smaller value if the current
  // function is marked as optimize-for-size, and the unroll threshold was
  // not user specified.
  CurrentThreshold = UnrollThreshold;
  if (Header->getParent()->hasFnAttr(Attribute::OptimizeForSize) &&
      UnrollThreshold.getNumOccurrences() == 0)
    CurrentThreshold = OptSizeUnrollThreshold;

  // Find trip count
  unsigned TripCount = L->getSmallConstantTripCount();
  unsigned Count = UnrollCount;

  // Automatically select an unroll count.
  if (Count == 0) {
    // Conservative heuristic: if we know the trip count, see if we can
    // completely unroll (subject to the threshold, checked below); otherwise
    // try to find greatest modulo of the trip count which is still under
    // threshold value.
    if (TripCount == 0)
      return false;
    Count = TripCount;
  }

  // Enforce the threshold.
  if (CurrentThreshold != NoThreshold) {
    unsigned NumInlineCandidates;
    unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates);
    DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
    if (NumInlineCandidates != 0) {
      DEBUG(dbgs() << "  Not unrolling loop with inlinable calls.\n");
      return false;
    }

    // NOTE: We multiply by the loop depth because unrolling inner loops of
    // very deep nests tends to result in high register pressure, which we don't
    // currently recover from very well.  When and if the register allocator/
    // spiller improves to compensate, this should be re-evaluated.
    uint64_t Size = (uint64_t)LoopSize*Count*L->getLoopDepth();
    if (TripCount != 1 && Size > CurrentThreshold) {
      DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
            << " because size: " << Size << ">" << CurrentThreshold << "\n");
      if (!UnrollAllowPartial) {
        DEBUG(dbgs() << "  will not try to unroll partially because "
              << "-unroll-allow-partial not given\n");
        return false;
      }
      // Reduce unroll count to be modulo of TripCount for partial unrolling
      Count = CurrentThreshold / LoopSize;
      while (Count != 0 && TripCount%Count != 0) {
        Count--;
      }
      if (Count < 2) {
        DEBUG(dbgs() << "  could not unroll partially\n");
        return false;
      }
      DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
    }
  }

  // Unroll the loop.
  Function *F = L->getHeader()->getParent();
  if (!UnrollLoop(L, Count, LI, &LPM))
    return false;

  // FIXME: Reconstruct dom info, because it is not preserved properly.
  if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>())
    DT->runOnFunction(*F);
  return true;
}
<|endoftext|>