<commit_before>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
    if (Function *F = CI->getCalledFunction())
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args;
        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
            Args.push_back(Op);
          else
            return 0;
        return ConstantFoldCall(F, Args);
      }
    return 0;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
    return ConstantExpr::get(I->getOpcode(), Op0, Op1);

  switch (I->getOpcode()) {
  default: return 0;
  case Instruction::Cast:
    return ConstantExpr::getCast(Op0, I->getType());
  case Instruction::Select:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getSelect(Op0, Op1, Op2);
    return 0;
  case Instruction::GetElementPtr:
    std::vector<Constant*> IdxList;
    IdxList.reserve(I->getNumOperands()-1);
    if (Op1) IdxList.push_back(Op1);
    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
        IdxList.push_back(C);
      else
        return 0;  // Non-constant operand
    return ConstantExpr::getGetElementPtr(Op0, IdxList);
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool llvm::canConstantFoldCallTo(Function *F) {
  const std::string &Name = F->getName();

  switch (F->getIntrinsicID()) {
  case Intrinsic::isnan: return true;
  default: break;
  }

  return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt" ||
         Name == "log" || Name == "log10" || Name == "exp" || Name == "pow" ||
         Name == "acos" || Name == "asin" || Name == "atan" || Name == "fmod";
}

static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
                                const Type *Ty) {
  errno = 0;
  V = NativeFP(V);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  return 0;
}

/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *llvm::ConstantFoldCall(Function *F,
                                 const std::vector<Constant*> &Operands) {
  const std::string &Name = F->getName();
  const Type *Ty = F->getReturnType();

  if (Operands.size() == 1) {
    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
      double V = Op->getValue();
      if (Name == "llvm.isnan")
        return ConstantBool::get(isnan(V));
      else if (Name == "sin")
        return ConstantFP::get(Ty, sin(V));
      else if (Name == "cos")
        return ConstantFP::get(Ty, cos(V));
      else if (Name == "tan")
        return ConstantFP::get(Ty, tan(V));
      else if (Name == "sqrt" && V >= 0)
        return ConstantFP::get(Ty, sqrt(V));
      else if (Name == "exp")
        return ConstantFP::get(Ty, exp(V));
      else if (Name == "log" && V > 0)
        return ConstantFP::get(Ty, log(V));
      else if (Name == "log10")
        return ConstantFoldFP(log10, V, Ty);
      else if (Name == "acos")
        return ConstantFoldFP(acos, V, Ty);
      else if (Name == "asin")
        return ConstantFoldFP(asin, V, Ty);
      else if (Name == "atan")
        return ConstantFP::get(Ty, atan(V));
    }
  } else if (Operands.size() == 2) {
    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0]))
      if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
        double Op1V = Op1->getValue(), Op2V = Op2->getValue();

        if (Name == "pow") {
          errno = 0;
          double V = pow(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "fmod") {
          errno = 0;
          double V = fmod(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        }
      }
  }
  return 0;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  return I->use_empty() && !I->mayWriteToMemory() && !isa<TerminatorInst>(I);
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}

//===----------------------------------------------------------------------===//
//  PHI Instruction Simplification
//

/// hasConstantValue - If the specified PHI node always merges together the same
/// value, return the value, otherwise return null.
///
Value *llvm::hasConstantValue(PHINode *PN) {
  // If the PHI node only has one incoming value, eliminate the PHI node...
  if (PN->getNumIncomingValues() == 1)
    return PN->getIncomingValue(0);

  // Otherwise if all of the incoming values are the same for the PHI, replace
  // the PHI node with the incoming value.
  //
  Value *InVal = 0;
  for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
    if (PN->getIncomingValue(i) != PN)  // Not the PHI node itself...
      if (InVal && PN->getIncomingValue(i) != InVal)
        return 0;  // Not the same, bail out.
      else
        InVal = PN->getIncomingValue(i);

  // The only case that could cause InVal to be null is if we have a PHI node
  // that only has entries for itself.  In this case, there is no entry into the
  // loop, so kill the PHI.
  //
  if (InVal == 0) InVal = Constant::getNullValue(PN->getType());

  // All of the incoming values are the same, return the value now.
  return InVal;
}
<commit_msg>Add constant folding capabilities to the isunordered intrinsic.<commit_after>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
    if (Function *F = CI->getCalledFunction())
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args;
        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
            Args.push_back(Op);
          else
            return 0;
        return ConstantFoldCall(F, Args);
      }
    return 0;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
    return ConstantExpr::get(I->getOpcode(), Op0, Op1);

  switch (I->getOpcode()) {
  default: return 0;
  case Instruction::Cast:
    return ConstantExpr::getCast(Op0, I->getType());
  case Instruction::Select:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getSelect(Op0, Op1, Op2);
    return 0;
  case Instruction::GetElementPtr:
    std::vector<Constant*> IdxList;
    IdxList.reserve(I->getNumOperands()-1);
    if (Op1) IdxList.push_back(Op1);
    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
        IdxList.push_back(C);
      else
        return 0;  // Non-constant operand
    return ConstantExpr::getGetElementPtr(Op0, IdxList);
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool llvm::canConstantFoldCallTo(Function *F) {
  const std::string &Name = F->getName();

  switch (F->getIntrinsicID()) {
  case Intrinsic::isnan: return true;
  case Intrinsic::isunordered: return true;
  default: break;
  }

  return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt" ||
         Name == "log" || Name == "log10" || Name == "exp" || Name == "pow" ||
         Name == "acos" || Name == "asin" || Name == "atan" || Name == "fmod";
}

static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
                                const Type *Ty) {
  errno = 0;
  V = NativeFP(V);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  return 0;
}

/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *llvm::ConstantFoldCall(Function *F,
                                 const std::vector<Constant*> &Operands) {
  const std::string &Name = F->getName();
  const Type *Ty = F->getReturnType();

  if (Operands.size() == 1) {
    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
      double V = Op->getValue();
      if (Name == "llvm.isnan")
        return ConstantBool::get(isnan(V));
      else if (Name == "sin")
        return ConstantFP::get(Ty, sin(V));
      else if (Name == "cos")
        return ConstantFP::get(Ty, cos(V));
      else if (Name == "tan")
        return ConstantFP::get(Ty, tan(V));
      else if (Name == "sqrt" && V >= 0)
        return ConstantFP::get(Ty, sqrt(V));
      else if (Name == "exp")
        return ConstantFP::get(Ty, exp(V));
      else if (Name == "log" && V > 0)
        return ConstantFP::get(Ty, log(V));
      else if (Name == "log10")
        return ConstantFoldFP(log10, V, Ty);
      else if (Name == "acos")
        return ConstantFoldFP(acos, V, Ty);
      else if (Name == "asin")
        return ConstantFoldFP(asin, V, Ty);
      else if (Name == "atan")
        return ConstantFP::get(Ty, atan(V));
    }
  } else if (Operands.size() == 2) {
    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0]))
      if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
        double Op1V = Op1->getValue(), Op2V = Op2->getValue();

        if (Name == "llvm.isunordered")
          return ConstantBool::get(isnan(Op1V) | isnan(Op2V));
        else if (Name == "pow") {
          errno = 0;
          double V = pow(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "fmod") {
          errno = 0;
          double V = fmod(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        }
      }
  }
  return 0;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  return I->use_empty() && !I->mayWriteToMemory() && !isa<TerminatorInst>(I);
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}

//===----------------------------------------------------------------------===//
//  PHI Instruction Simplification
//

/// hasConstantValue - If the specified PHI node always merges together the same
/// value, return the value, otherwise return null.
///
Value *llvm::hasConstantValue(PHINode *PN) {
  // If the PHI node only has one incoming value, eliminate the PHI node...
  if (PN->getNumIncomingValues() == 1)
    return PN->getIncomingValue(0);

  // Otherwise if all of the incoming values are the same for the PHI, replace
  // the PHI node with the incoming value.
  //
  Value *InVal = 0;
  for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
    if (PN->getIncomingValue(i) != PN)  // Not the PHI node itself...
      if (InVal && PN->getIncomingValue(i) != InVal)
        return 0;  // Not the same, bail out.
      else
        InVal = PN->getIncomingValue(i);

  // The only case that could cause InVal to be null is if we have a PHI node
  // that only has entries for itself.  In this case, there is no entry into the
  // loop, so kill the PHI.
  //
  if (InVal == 0) InVal = Constant::getNullValue(PN->getType());

  // All of the incoming values are the same, return the value now.
  return InVal;
}
<|endoftext|>


<commit_before>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
    if (Function *F = CI->getCalledFunction())
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args;
        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
            Args.push_back(Op);
          else
            return 0;
        return ConstantFoldCall(F, Args);
      }
    return 0;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
    return ConstantExpr::get(I->getOpcode(), Op0, Op1);

  switch (I->getOpcode()) {
  default: return 0;
  case Instruction::Cast:
    return ConstantExpr::getCast(Op0, I->getType());
  case Instruction::Select:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getSelect(Op0, Op1, Op2);
    return 0;
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Op0, Op1);
  case Instruction::InsertElement:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getInsertElement(Op0, Op1, Op2);
    return 0;
  case Instruction::ShuffleVector:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
    return 0;
  case Instruction::GetElementPtr:
    std::vector<Constant*> IdxList;
    IdxList.reserve(I->getNumOperands()-1);
    if (Op1) IdxList.push_back(Op1);
    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
        IdxList.push_back(C);
      else
        return 0;  // Non-constant operand
    return ConstantExpr::getGetElementPtr(Op0, IdxList);
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
                                                       ConstantExpr *CE) {
  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
    return 0;  // Do not allow stepping over the value!

  // Loop over all of the operands, tracking down which value we are
  // addressing...
  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
  for (++I; I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
      assert(CU->getValue() < STy->getNumElements() &&
             "Struct index out of range!");
      unsigned El = (unsigned)CU->getValue();
      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
        C = CS->getOperand(El);
      } else if (isa<ConstantAggregateZero>(C)) {
        C = Constant::getNullValue(STy->getElementType(El));
      } else if (isa<UndefValue>(C)) {
        C = UndefValue::get(STy->getElementType(El));
      } else {
        return 0;
      }
    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= ATy->getNumElements())
         return 0;
        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
          C = CA->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(ATy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(ATy->getElementType());
        else
          return 0;
      } else if (const PackedType *PTy = dyn_cast<PackedType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= PTy->getNumElements())
          return 0;
        if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C))
          C = CP->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(PTy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(PTy->getElementType());
        else
          return 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  return C;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  if (!I->use_empty() || isa<TerminatorInst>(I)) return false;

  if (!I->mayWriteToMemory()) return true;

  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction()) {
      unsigned IntrinsicID = F->getIntrinsicID();
#define GET_SIDE_EFFECT_INFO
#include "llvm/Intrinsics.gen"
#undef GET_SIDE_EFFECT_INFO
    }
  return false;
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}
<commit_msg>Refactor some code to expose an interface to constant fold and instruction given it's opcode, typeand operands.<commit_after>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
    if (Constant *Op0 = dyn_cast<Constant>(I->getOperand(0)))
      if (Constant *Op1 = dyn_cast<Constant>(I->getOperand(1)))
        return ConstantExpr::get(I->getOpcode(), Op0, Op1);
    return 0;  // Operands not constants.
  }

  // Scan the operand list, checking to see if the are all constants, if so,
  // hand off to ConstantFoldInstOperands.
  std::vector<Constant*> Ops;
  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
    if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
      Ops.push_back(Op);
    else
      return 0;  // All operands not constant!

  return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops);
}

/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified opcode and operands.  If successful, the constant result is
/// returned, if not, null is returned.  Note that this function can fail when
/// attempting to fold instructions like loads and stores, which have no
/// constant expression form.
///
Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
                                         const std::vector<Constant*> &Ops) {
  if (Opc >= Instruction::BinaryOpsBegin && Opc < Instruction::BinaryOpsEnd)
    return ConstantExpr::get(Opc, Ops[0], Ops[1]);

  switch (Opc) {
  default: return 0;
  case Instruction::Call:
    if (Function *F = dyn_cast<Function>(Ops[0])) {
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args(Ops.begin()+1, Ops.end());
        return ConstantFoldCall(F, Args);
      }
    }
    return 0;
  case Instruction::Shl:
  case Instruction::Shr:
    return ConstantExpr::get(Opc, Ops[0], Ops[1]);
  case Instruction::Cast:
    return ConstantExpr::getCast(Ops[0], DestTy);
  case Instruction::Select:
    return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
  case Instruction::InsertElement:
    return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
  case Instruction::ShuffleVector:
    return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
  case Instruction::GetElementPtr:
    return ConstantExpr::getGetElementPtr(Ops[0],
                                          std::vector<Constant*>(Ops.begin()+1,
                                                                 Ops.end()));
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
                                                       ConstantExpr *CE) {
  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
    return 0;  // Do not allow stepping over the value!

  // Loop over all of the operands, tracking down which value we are
  // addressing...
  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
  for (++I; I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
      assert(CU->getValue() < STy->getNumElements() &&
             "Struct index out of range!");
      unsigned El = (unsigned)CU->getValue();
      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
        C = CS->getOperand(El);
      } else if (isa<ConstantAggregateZero>(C)) {
        C = Constant::getNullValue(STy->getElementType(El));
      } else if (isa<UndefValue>(C)) {
        C = UndefValue::get(STy->getElementType(El));
      } else {
        return 0;
      }
    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= ATy->getNumElements())
         return 0;
        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
          C = CA->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(ATy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(ATy->getElementType());
        else
          return 0;
      } else if (const PackedType *PTy = dyn_cast<PackedType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= PTy->getNumElements())
          return 0;
        if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C))
          C = CP->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(PTy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(PTy->getElementType());
        else
          return 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  return C;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  if (!I->use_empty() || isa<TerminatorInst>(I)) return false;

  if (!I->mayWriteToMemory()) return true;

  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction()) {
      unsigned IntrinsicID = F->getIntrinsicID();
#define GET_SIDE_EFFECT_INFO
#include "llvm/Intrinsics.gen"
#undef GET_SIDE_EFFECT_INFO
    }
  return false;
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>/*
 * face-cleaner.cpp
 *
 *  Created on: Nov 15, 2014
 *      Author: Michael Williams
 */

#include "facerecogntion/face-cleaner.h"
#include <vector>
#include <stdio.h>

using namespace cv;
using namespace std;

namespace facerecogntion{

Mat clean_face(Mat face){
	CascadeClassifier filter;
	filter.load( FACE_FILTER );
	vector<Rect> faces;
	Mat gray_face;
	cvtColor( face, gray_face, CV_BGR2GRAY );
	gray_face.convertTo(gray_face, CV_8UC1);
	equalizeHist( gray_face, gray_face );
	filter.detectMultiScale( gray_face, faces, 1.1, 2, 0, Size(100, 100) );
	Rect roi;
	vector<Rect>::iterator it;
	for(it=faces.begin(); it != faces.end(); it++){
		if(it->area() > roi.area()){
			roi = (*it);
		}
	}
	Mat tmp;
	cvtColor(gray_face(roi), tmp, CV_BGR2GRAY);
	return tmp;

}

}
<commit_msg>More cleaning to the images<commit_after>/*
 * face-cleaner.cpp
 *
 *  Created on: Nov 15, 2014
 *      Author: Michael Williams
 */

#include "facerecogntion/face-cleaner.h"
#include <vector>
#include <stdio.h>

using namespace cv;
using namespace std;

namespace facerecogntion{

Mat clean_face(Mat face){
	CascadeClassifier filter;
	filter.load( FACE_FILTER );
	vector<Rect> faces;
	Mat gray_face;
	cvtColor( face, gray_face, CV_BGR2GRAY );
	gray_face.convertTo(gray_face, CV_8UC1);
	equalizeHist( gray_face, gray_face );
	filter.detectMultiScale( gray_face, faces, 1.1, 2, 0, Size(100, 100) );
	Rect roi;
	vector<Rect>::iterator it;
	for(it=faces.begin(); it != faces.end(); it++){
		if(it->area() > roi.area()){
			roi = (*it);
		}
	}
	Mat tmp;
	gray_face(roi).convertTo(tmp, CV_8UC1);
	equalizeHist( tmp, tmp );
	return tmp;

}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: lockfile.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-25 13:51:15 $
 *
 *  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): lars.oppermann@sun.com
 *
 *
 ************************************************************************/
#include <stdlib.h>
#include <time.h>
#include <sal/types.h>
#include <osl/file.hxx>
#include <osl/socket.hxx>
#include <osl/security.hxx>
#include <unotools/bootstrap.hxx>
#include <vcl/msgbox.hxx>
#include <tools/string.hxx>
#include <tools/config.hxx>

#include "desktopresid.hxx"
#include "lockfile.hxx"
#include "desktop.hrc"

using namespace ::osl;
using namespace ::rtl;
using namespace ::utl;

namespace desktop {

    // initialize static members...
    // lock suffix
    const OUString Lockfile::m_aSuffix = OUString::createFromAscii( "/.lock" );
    // values for datafile
    const ByteString Lockfile::m_aGroup( "Lockdata" );
    const ByteString Lockfile::m_aUserkey( "User" );
    const ByteString Lockfile::m_aHostkey( "Host" );
    const ByteString Lockfile::m_aStampkey( "Stamp" );
    const ByteString Lockfile::m_aTimekey( "Time" );

    Lockfile::Lockfile(void)
    :m_bRemove(sal_False)
    ,m_bIsLocked(sal_False)
    {
        // build the file-url to use for the lock
        OUString aUserPath;
        Bootstrap::locateUserInstallation( aUserPath );
        m_aLockname = aUserPath + m_aSuffix;

        // generate ID
        const int nIdBytes = 16;
        char tmpId[nIdBytes*2+1];
        time_t t;
        srand( (unsigned)(t = time( NULL )) );
        int tmpByte = 0;
        for (int i = 0; i<nIdBytes; i++) {
            tmpByte = rand( ) % 0xFF;
            sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked
        }
        tmpId[nIdBytes*2]=0x00;
        m_aId = OUString::createFromAscii( tmpId );

        // generate date string
        char *tmpTime = ctime( &t );
        tmpTime[24] = 0x00; // buffer is always 26 chars, remove '\n'
        m_aDate = OUString::createFromAscii( tmpTime );

        // try to create file
        File aFile(m_aLockname);
        if (aFile.open( OpenFlag_Create ) == File::E_EXIST) {
            m_bIsLocked = sal_True;
        } else {
            // new lock created
            aFile.close( );
            syncToFile( );
            m_bRemove = sal_True;
        }
    }

    sal_Bool Lockfile::check( void )
    {

        if (m_bIsLocked) {
            // lock existed, ask user what to do
            if (isStale() || execWarning( ) == RET_YES) {
                // remove file and create new
                File::remove( m_aLockname );
                File aFile(m_aLockname);
                aFile.open( OpenFlag_Create );
                aFile.close( );
                syncToFile( );
                m_bRemove = sal_True;
                return sal_True;
            } else {
                //leave alone and return false
                m_bRemove = sal_False;
                return sal_False;
            }
        } else {
            // lock was created by us
            return sal_True;
        }
    }

    sal_Bool Lockfile::isStale( void ) const
    {
        // this checks whether the lockfile was created on the same
        // host by the same user. Should this be the case it is safe
        // to assume that it is a stale lookfile which can be overwritten
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);
        ByteString aHost  = aConfig.ReadKey( m_aHostkey );
        ByteString aUser  = aConfig.ReadKey( m_aUserkey );
        // lockfile from same host?
        oslSocketResult sRes;
        ByteString myHost  = OUStringToOString(
            SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
        if (aHost == myHost) {
            // lockfile by same UID
            OUString myUserName;
            Security aSecurity;
            aSecurity.getUserName( myUserName );
            ByteString myUser  = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US );
            if (aUser == myUser)
                return sal_True;
        }
        return sal_False;
    }

    void Lockfile::syncToFile( void ) const
    {
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);

        // get information
        oslSocketResult sRes;
        ByteString aHost  = OUStringToOString(
            SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
        OUString aUserName;
        Security aSecurity;
        aSecurity.getUserName( aUserName );
        ByteString aUser  = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US );
        ByteString aTime  = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US );
        ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );

        // write information
        aConfig.WriteKey( m_aUserkey,  aUser );
        aConfig.WriteKey( m_aHostkey,  aHost );
        aConfig.WriteKey( m_aStampkey, aStamp );
        aConfig.WriteKey( m_aTimekey,  aTime );
        aConfig.Flush( );
    }

    short Lockfile::execWarning(void) const
    {
        // read information from lock
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);
        ByteString aHost  = aConfig.ReadKey( m_aHostkey );
        ByteString aUser  = aConfig.ReadKey( m_aUserkey );
        ByteString aStamp = aConfig.ReadKey( m_aStampkey );
        ByteString aTime  = aConfig.ReadKey( m_aTimekey );

        // display warning and return response
        QueryBox aBox( NULL, DesktopResId( QBX_USERDATALOCKED ) );
        // set box title
        String aTitle = String( DesktopResId( STR_TITLE_USERDATALOCKED ));
        aBox.SetText( aTitle );
        // insert values...
        String aMsgText = aBox.GetMessText( );
        aMsgText.SearchAndReplaceAscii( "$u", String( aUser, RTL_TEXTENCODING_ASCII_US) );
        aMsgText.SearchAndReplaceAscii( "$h", String( aHost, RTL_TEXTENCODING_ASCII_US) );
        aMsgText.SearchAndReplaceAscii( "$t", String( aTime, RTL_TEXTENCODING_ASCII_US) );
        aBox.SetMessText(aMsgText);
        // do it
        return aBox.Execute( );
    }

    void Lockfile::clean( void )
    {
        if ( m_bRemove )
        {
            File::remove( m_aLockname );
            m_bRemove = sal_False;
        }
    }

    Lockfile::~Lockfile( void )
    {
        // unlock userdata by removing file
        if ( m_bRemove )
            File::remove( m_aLockname );
    }
}
<commit_msg>INTEGRATION: CWS fwk01 (1.2.2.5.16); FILE MERGED 2003/04/01 14:03:31 lo 1.2.2.5.16.1: #i12907# allow startup without splashscreen component being loaded<commit_after>/*************************************************************************
 *
 *  $RCSfile: lockfile.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2003-04-04 17:22:51 $
 *
 *  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): lars.oppermann@sun.com
 *
 *
 ************************************************************************/
#include <stdlib.h>
#include <time.h>
#include <sal/types.h>
#include <osl/file.hxx>
#include <osl/socket.hxx>
#include <osl/security.hxx>
#include <unotools/bootstrap.hxx>
#include <vcl/msgbox.hxx>
#include <tools/string.hxx>
#include <tools/config.hxx>

#include "desktopresid.hxx"
#include "lockfile.hxx"
#include "desktop.hrc"

using namespace ::osl;
using namespace ::rtl;
using namespace ::utl;

namespace desktop {

    // initialize static members...
    // lock suffix
    const OUString Lockfile::m_aSuffix = OUString::createFromAscii( "/.lock" );
    // values for datafile
    const ByteString Lockfile::m_aGroup( "Lockdata" );
    const ByteString Lockfile::m_aUserkey( "User" );
    const ByteString Lockfile::m_aHostkey( "Host" );
    const ByteString Lockfile::m_aStampkey( "Stamp" );
    const ByteString Lockfile::m_aTimekey( "Time" );

    Lockfile::Lockfile(void)
    :m_bRemove(sal_False)
    ,m_bIsLocked(sal_False)
    {
        // build the file-url to use for the lock
        OUString aUserPath;
        Bootstrap::locateUserInstallation( aUserPath );
        m_aLockname = aUserPath + m_aSuffix;

        // generate ID
        const int nIdBytes = 16;
        char tmpId[nIdBytes*2+1];
        time_t t;
        srand( (unsigned)(t = time( NULL )) );
        int tmpByte = 0;
        for (int i = 0; i<nIdBytes; i++) {
            tmpByte = rand( ) % 0xFF;
            sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked
        }
        tmpId[nIdBytes*2]=0x00;
        m_aId = OUString::createFromAscii( tmpId );

        // generate date string
        char *tmpTime = ctime( &t );
        tmpTime[24] = 0x00; // buffer is always 26 chars, remove '\n'
        m_aDate = OUString::createFromAscii( tmpTime );

        // try to create file
        File aFile(m_aLockname);
        if (aFile.open( OpenFlag_Create ) == File::E_EXIST) {
            m_bIsLocked = sal_True;
        } else {
            // new lock created
            aFile.close( );
            syncToFile( );
            m_bRemove = sal_True;
        }
    }

    sal_Bool Lockfile::check( void )
    {

        if (m_bIsLocked) {
            // lock existed, ask user what to do
            if (isStale() || execWarning( ) == RET_YES) {
                // remove file and create new
                File::remove( m_aLockname );
                File aFile(m_aLockname);
                aFile.open( OpenFlag_Create );
                aFile.close( );
                syncToFile( );
                m_bRemove = sal_True;
                return sal_True;
            } else {
                //leave alone and return false
                m_bRemove = sal_False;
                return sal_False;
            }
        } else {
            // lock was created by us
            return sal_True;
        }
    }

    sal_Bool Lockfile::isStale( void ) const
    {
        // this checks whether the lockfile was created on the same
        // host by the same user. Should this be the case it is safe
        // to assume that it is a stale lockfile which can be overwritten
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);
        ByteString aHost  = aConfig.ReadKey( m_aHostkey );
        ByteString aUser  = aConfig.ReadKey( m_aUserkey );
        // lockfile from same host?
        oslSocketResult sRes;
        ByteString myHost  = OUStringToOString(
            SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
        if (aHost == myHost) {
            // lockfile by same UID
            OUString myUserName;
            Security aSecurity;
            aSecurity.getUserName( myUserName );
            ByteString myUser  = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US );
            if (aUser == myUser)
                return sal_True;
        }
        return sal_False;
    }

    void Lockfile::syncToFile( void ) const
    {
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);

        // get information
        oslSocketResult sRes;
        ByteString aHost  = OUStringToOString(
            SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
        OUString aUserName;
        Security aSecurity;
        aSecurity.getUserName( aUserName );
        ByteString aUser  = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US );
        ByteString aTime  = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US );
        ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );

        // write information
        aConfig.WriteKey( m_aUserkey,  aUser );
        aConfig.WriteKey( m_aHostkey,  aHost );
        aConfig.WriteKey( m_aStampkey, aStamp );
        aConfig.WriteKey( m_aTimekey,  aTime );
        aConfig.Flush( );
    }

    short Lockfile::execWarning(void) const
    {
        // read information from lock
        String aLockname = m_aLockname;
        Config aConfig(aLockname);
        aConfig.SetGroup(m_aGroup);
        ByteString aHost  = aConfig.ReadKey( m_aHostkey );
        ByteString aUser  = aConfig.ReadKey( m_aUserkey );
        ByteString aStamp = aConfig.ReadKey( m_aStampkey );
        ByteString aTime  = aConfig.ReadKey( m_aTimekey );

        // display warning and return response
        QueryBox aBox( NULL, DesktopResId( QBX_USERDATALOCKED ) );
        // set box title
        String aTitle = String( DesktopResId( STR_TITLE_USERDATALOCKED ));
        aBox.SetText( aTitle );
        // insert values...
        String aMsgText = aBox.GetMessText( );
        aMsgText.SearchAndReplaceAscii( "$u", String( aUser, RTL_TEXTENCODING_ASCII_US) );
        aMsgText.SearchAndReplaceAscii( "$h", String( aHost, RTL_TEXTENCODING_ASCII_US) );
        aMsgText.SearchAndReplaceAscii( "$t", String( aTime, RTL_TEXTENCODING_ASCII_US) );
        aBox.SetMessText(aMsgText);
        // do it
        return aBox.Execute( );
    }

    void Lockfile::clean( void )
    {
        if ( m_bRemove )
        {
            File::remove( m_aLockname );
            m_bRemove = sal_False;
        }
    }

    Lockfile::~Lockfile( void )
    {
        // unlock userdata by removing file
        if ( m_bRemove )
            File::remove( m_aLockname );
    }
}
<|endoftext|>


<commit_before>/*
   Copyright(c) 2004 John J.Bolton

   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
   (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "ZHash.h"

#include "Chess/Board.h"
#include "Chess/Piece.h"
#include "Chess/Position.h"

#include "Misc/Random.h"

#include <cassert>

ZHash::ZValueTable const ZHash::zValueTable_;

namespace
{
    uint64_t generateRandomZ(RandomMT & rng)
    {
        // Z is 63 bits and RandomMT is 32 bits so we have to concatenate two numbers together to make a Z value.
        return ((uint64_t(rng()) << 32) | rng()) & 0x7fffffffffffffff;
    }
} // anonymous namespace

ZHash::ZHash(Z z /* = EMPTY */)
    : value_(z)
{
}

ZHash::ZHash(Board const & board,
             Color         whoseTurn,
             unsigned      castleStatus /* = 0*/,
             Color         ePColor /* = INVALID*/,
             int           ePColumn /* = -1*/,
             bool          fiftyMoveRule /* = false */)
{
    value_ = 0;

    for (int i = 0; i < Board::SIZE; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            Piece const * const piece = board.pieceAt(i, j);
            if (piece)
                add(piece, Position(i, j));
        }
    }

    if (whoseTurn != Color::WHITE)
        turn();

    if (castleStatus != 0)
        castle(castleStatus);

    if ((ePColor != Color::INVALID) && (ePColumn >= 0))
        enPassant(ePColor, ePColumn);

    if (fiftyMoveRule)
        fifty();
}

ZHash ZHash::add(Piece const * piece, Position const & position)
{
    value_ ^= zValueTable_.pieceValue((int)piece->color(), (int)piece->type(), position.row, position.column);
    return *this;
}

ZHash ZHash::remove(Piece const * piece, Position const & position)
{
    value_ ^= zValueTable_.pieceValue((int)piece->color(), (int)piece->type(), position.row, position.column);
    return *this;
}

ZHash ZHash::move(Piece const * piece, Position const & from, Position const & to)
{
    remove(piece, from);
    return add(piece, to);
}

ZHash ZHash::turn()
{
    value_ ^= zValueTable_.turnValue();
    return *this;
}

ZHash ZHash::castle(unsigned mask)
{
    assert(NUMBER_OF_CASTLE_BITS == 8);
    assert(CASTLE_AVAILABILITY_MASK == 0xf0);
    for (int i = 0; i < 4; ++i)
    {
        if (mask & (0x10 << i))
            value_ ^= zValueTable_.castleValue(i);
    }
    return *this;
}

ZHash ZHash::enPassant(Color color, int column)
{
    value_ ^= zValueTable_.enPassantValue((int)color, column);
    return *this;
}

ZHash ZHash::fifty()
{
    value_ ^= zValueTable_.fiftyValue();
    return *this;
}

bool ZHash::isUndefined() const
{
    // The value is undefined if the high order bit is set
    return static_cast<int64_t>(value_) < 0;
}

ZHash::ZValueTable::ZValueTable()
{
    RandomMT rng(0);

    // Generate piece values

    for (int i = 0; i < NUMBER_OF_COLORS; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            for (int k = 0; k < Board::SIZE; ++k)
            {
                for (int m = 0; m < NUMBER_OF_PIECE_TYPES; ++m)
                {
                    pieceValues_[i][j][k][m] = generateRandomZ(rng);
                }
            }
        }
    }

    // Generate castle values

    for (auto & v : castleValues_)
    {
        v = generateRandomZ(rng);
    }

    // Generate en passant values

    for (int i = 0; i < NUMBER_OF_COLORS; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            enPassantValues_[i][j] = generateRandomZ(rng);
        }
    }

    // Generate fifty-move rule value

    fiftyValue_ = generateRandomZ(rng);

    // Generate turn value

    turnValue_ = generateRandomZ(rng);
}

ZHash::Z ZHash::ZValueTable::pieceValue(int color, int type, int row, int column) const
{
    return pieceValues_[color][row][column][type];
}

ZHash::Z ZHash::ZValueTable::castleValue(int castle) const
{
    return castleValues_[castle];
}

ZHash::Z ZHash::ZValueTable::enPassantValue(int color, int column) const
{
    return enPassantValues_[color][column];
}

ZHash::Z ZHash::ZValueTable::fiftyValue() const
{
    return fiftyValue_;
}

ZHash::Z ZHash::ZValueTable::turnValue() const
{
    return turnValue_;
}

bool operator ==(ZHash const & x, ZHash const & y)
{
    return x.value_ == y.value_;
}
<commit_msg>Switched to std::random<commit_after>/*
   Copyright(c) 2004 John J.Bolton

   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
   (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "ZHash.h"

#include "Chess/Board.h"
#include "Chess/Piece.h"
#include "Chess/Position.h"

#include <cassert>
#include <random>

ZHash::ZValueTable const ZHash::zValueTable_;

ZHash::ZHash(Z z /* = EMPTY */)
    : value_(z)
{
}

ZHash::ZHash(Board const & board,
             Color         whoseTurn,
             unsigned      castleStatus /* = 0*/,
             Color         ePColor /* = INVALID*/,
             int           ePColumn /* = -1*/,
             bool          fiftyMoveRule /* = false */)
{
    value_ = 0;

    for (int i = 0; i < Board::SIZE; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            Piece const * const piece = board.pieceAt(i, j);
            if (piece)
                add(piece, Position(i, j));
        }
    }

    if (whoseTurn != Color::WHITE)
        turn();

    if (castleStatus != 0)
        castle(castleStatus);

    if ((ePColor != Color::INVALID) && (ePColumn >= 0))
        enPassant(ePColor, ePColumn);

    if (fiftyMoveRule)
        fifty();
}

ZHash ZHash::add(Piece const * piece, Position const & position)
{
    value_ ^= zValueTable_.pieceValue((int)piece->color(), (int)piece->type(), position.row, position.column);
    return *this;
}

ZHash ZHash::remove(Piece const * piece, Position const & position)
{
    value_ ^= zValueTable_.pieceValue((int)piece->color(), (int)piece->type(), position.row, position.column);
    return *this;
}

ZHash ZHash::move(Piece const * piece, Position const & from, Position const & to)
{
    remove(piece, from);
    return add(piece, to);
}

ZHash ZHash::turn()
{
    value_ ^= zValueTable_.turnValue();
    return *this;
}

ZHash ZHash::castle(unsigned mask)
{
    assert(NUMBER_OF_CASTLE_BITS == 8);
    assert(CASTLE_AVAILABILITY_MASK == 0xf0);
    for (int i = 0; i < 4; ++i)
    {
        if (mask & (0x10 << i))
            value_ ^= zValueTable_.castleValue(i);
    }
    return *this;
}

ZHash ZHash::enPassant(Color color, int column)
{
    value_ ^= zValueTable_.enPassantValue((int)color, column);
    return *this;
}

ZHash ZHash::fifty()
{
    value_ ^= zValueTable_.fiftyValue();
    return *this;
}

bool ZHash::isUndefined() const
{
    // The value is undefined if the high order bit is set
    return static_cast<int64_t>(value_) < 0;
}

ZHash::ZValueTable::ZValueTable()
{
    std::mt19937_64 rng;
    static_assert(sizeof(std::mt19937_64::result_type) == 8);

    // Generate piece values

    for (int i = 0; i < NUMBER_OF_COLORS; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            for (int k = 0; k < Board::SIZE; ++k)
            {
                for (int m = 0; m < NUMBER_OF_PIECE_TYPES; ++m)
                {
                    pieceValues_[i][j][k][m] = rng();
                }
            }
        }
    }

    // Generate castle values

    for (auto & v : castleValues_)
    {
        v = rng();
    }

    // Generate en passant values

    for (int i = 0; i < NUMBER_OF_COLORS; ++i)
    {
        for (int j = 0; j < Board::SIZE; ++j)
        {
            enPassantValues_[i][j] = rng();
        }
    }

    // Generate fifty-move rule value

    fiftyValue_ = rng();

    // Generate turn value

    turnValue_ = rng();
}

ZHash::Z ZHash::ZValueTable::pieceValue(int color, int type, int row, int column) const
{
    return pieceValues_[color][row][column][type];
}

ZHash::Z ZHash::ZValueTable::castleValue(int castle) const
{
    return castleValues_[castle];
}

ZHash::Z ZHash::ZValueTable::enPassantValue(int color, int column) const
{
    return enPassantValues_[color][column];
}

ZHash::Z ZHash::ZValueTable::fiftyValue() const
{
    return fiftyValue_;
}

ZHash::Z ZHash::ZValueTable::turnValue() const
{
    return turnValue_;
}

bool operator ==(ZHash const & x, ZHash const & y)
{
    return x.value_ == y.value_;
}
<|endoftext|>