[llvm] r190328 - Revert patches to add case-range support for PR1255.

Bob Wilson bob.wilson at apple.com
Fri Sep 13 09:19:18 PDT 2013


The change touched a lot of code, but it shouldn't have made much change in the behavior.

On Sep 13, 2013, at 9:17 AM, Reed Kotler <Reed.Kotler at imgtec.com> wrote:

> I will look at it myself first today.
> 
> In the past, some of the regressions that we had from upstream just showed bugs that were always in our code but never showed up before.
> 
> It's just that if there are are small putbacks, it's easier to figure out what happened.
> I can look at the compiler changes and think about how that could have changed things.
> 
> With a large putback like this, I may have to really debug lencode first, which is a bigger task and then start
> to work backwards.
> 
> We have some scripts that automatically do the bisecting so I'm 99% sure that this set of changes is what caused the regression.
> 
> Reed
> 
> ________________________________________
> From: Bob Wilson [bob.wilson at apple.com]
> Sent: Friday, September 13, 2013 8:52 AM
> To: Reed Kotler
> Cc: llvm-commits at cs.uiuc.edu
> Subject: Re: [llvm] r190328 - Revert patches to add case-range support for PR1255.
> 
> Given the extent of that change, I would prefer to avoid reverting it.  Can you provide more information so that someone could debug this?
> 
> On Sep 12, 2013, at 6:53 PM, Reed Kotler <rkotler at mips.com> wrote:
> 
>> According to our bisect, this is the change that caused regression in the mips16 compiler for the lencod test in test-suite.
>> 
>> Our default testing mode for mips16 is -Os because the only point in using mips16 mode is for saving space.
>> 
>> I have not had a chance to debug lencod yet to understand why it does not work now.
>> 
>> Even though it's reverting some work; this is really in effect a huge patch to the compiler.
>> 
>> Reed
>> 
>> 
>> On 09/09/2013 12:14 PM, Bob Wilson wrote:
>>> Author: bwilson
>>> Date: Mon Sep  9 14:14:35 2013
>>> New Revision: 190328
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=190328&view=rev
>>> Log:
>>> Revert patches to add case-range support for PR1255.
>>> 
>>> The work on this project was left in an unfinished and inconsistent state.
>>> Hopefully someone will eventually get a chance to implement this feature, but
>>> in the meantime, it is better to put things back the way the were.  I have
>>> left support in the bitcode reader to handle the case-range bitcode format,
>>> so that we do not lose bitcode compatibility with the llvm 3.3 release.
>>> 
>>> This reverts the following commits: 155464, 156374, 156377, 156613, 156704,
>>> 156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575,
>>> 157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884,
>>> 157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100,
>>> 159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659,
>>> 159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736
>>> 
>>> Added:
>>>    llvm/trunk/test/Bitcode/case-ranges-3.3.ll
>>>    llvm/trunk/test/Bitcode/case-ranges-3.3.ll.bc
>>> Removed:
>>>    llvm/trunk/include/llvm/Support/IntegersSubset.h
>>>    llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
>>>    llvm/trunk/test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll
>>>    llvm/trunk/unittests/Support/IntegersSubsetTest.cpp
>>> Modified:
>>>    llvm/trunk/include/llvm/IR/Instructions.h
>>>    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>>>    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>>>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>>>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
>>>    llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp
>>>    llvm/trunk/lib/IR/Instructions.cpp
>>>    llvm/trunk/lib/IR/Verifier.cpp
>>>    llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
>>>    llvm/trunk/lib/Transforms/Instrumentation/DebugIR.cpp
>>>    llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
>>>    llvm/trunk/lib/Transforms/Utils/Local.cpp
>>>    llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
>>>    llvm/trunk/test/Transforms/LowerSwitch/feature.ll
>>>    llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp
>>>    llvm/trunk/unittests/IR/WaymarkTest.cpp
>>> 
>>> Modified: llvm/trunk/include/llvm/IR/Instructions.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/IR/Instructions.h (original)
>>> +++ llvm/trunk/include/llvm/IR/Instructions.h Mon Sep  9 14:14:35 2013
>>> @@ -23,8 +23,6 @@
>>> #include "llvm/IR/DerivedTypes.h"
>>> #include "llvm/IR/InstrTypes.h"
>>> #include "llvm/Support/ErrorHandling.h"
>>> -#include "llvm/Support/IntegersSubset.h"
>>> -#include "llvm/Support/IntegersSubsetMapping.h"
>>> #include <iterator>
>>> 
>>> namespace llvm {
>>> @@ -2457,31 +2455,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Bra
>>> class SwitchInst : public TerminatorInst {
>>>   void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
>>>   unsigned ReservedSpace;
>>> -  // Operands format:
>>>   // Operand[0]    = Value to switch on
>>>   // Operand[1]    = Default basic block destination
>>>   // Operand[2n  ] = Value to match
>>>   // Operand[2n+1] = BasicBlock to go to on match
>>> -
>>> -  // Store case values separately from operands list. We needn't User-Use
>>> -  // concept here, since it is just a case value, it will always constant,
>>> -  // and case value couldn't reused with another instructions/values.
>>> -  // Additionally:
>>> -  // It allows us to use custom type for case values that is not inherited
>>> -  // from Value. Since case value is a complex type that implements
>>> -  // the subset of integers, we needn't extract sub-constants within
>>> -  // slow getAggregateElement method.
>>> -  // For case values we will use std::list to by two reasons:
>>> -  // 1. It allows to add/remove cases without whole collection reallocation.
>>> -  // 2. In most of cases we needn't random access.
>>> -  // Currently case values are also stored in Operands List, but it will moved
>>> -  // out in future commits.
>>> -  typedef std::list<IntegersSubset> Subsets;
>>> -  typedef Subsets::iterator SubsetsIt;
>>> -  typedef Subsets::const_iterator SubsetsConstIt;
>>> -
>>> -  Subsets TheSubsets;
>>> -
>>>   SwitchInst(const SwitchInst &SI);
>>>   void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
>>>   void growOperands();
>>> @@ -2506,25 +2483,121 @@ protected:
>>>   virtual SwitchInst *clone_impl() const;
>>> public:
>>> 
>>> -  // FIXME: Currently there are a lot of unclean template parameters,
>>> -  // we need to make refactoring in future.
>>> -  // All these parameters are used to implement both iterator and const_iterator
>>> -  // without code duplication.
>>> -  // SwitchInstTy may be "const SwitchInst" or "SwitchInst"
>>> -  // ConstantIntTy may be "const ConstantInt" or "ConstantInt"
>>> -  // SubsetsItTy may be SubsetsConstIt or SubsetsIt
>>> -  // BasicBlockTy may be "const BasicBlock" or "BasicBlock"
>>> -  template <class SwitchInstTy, class ConstantIntTy,
>>> -            class SubsetsItTy, class BasicBlockTy>
>>> -    class CaseIteratorT;
>>> -
>>> -  typedef CaseIteratorT<const SwitchInst, const ConstantInt,
>>> -                        SubsetsConstIt, const BasicBlock> ConstCaseIt;
>>> -  class CaseIt;
>>> -
>>>   // -2
>>>   static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
>>> 
>>> +  template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
>>> +  class CaseIteratorT {
>>> +  protected:
>>> +
>>> +    SwitchInstTy *SI;
>>> +    unsigned Index;
>>> +
>>> +  public:
>>> +
>>> +    typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
>>> +
>>> +    /// Initializes case iterator for given SwitchInst and for given
>>> +    /// case number.
>>> +    CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
>>> +      this->SI = SI;
>>> +      Index = CaseNum;
>>> +    }
>>> +
>>> +    /// Initializes case iterator for given SwitchInst and for given
>>> +    /// TerminatorInst's successor index.
>>> +    static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
>>> +      assert(SuccessorIndex < SI->getNumSuccessors() &&
>>> +             "Successor index # out of range!");
>>> +      return SuccessorIndex != 0 ?
>>> +             Self(SI, SuccessorIndex - 1) :
>>> +             Self(SI, DefaultPseudoIndex);
>>> +    }
>>> +
>>> +    /// Resolves case value for current case.
>>> +    ConstantIntTy *getCaseValue() {
>>> +      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> +      return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
>>> +    }
>>> +
>>> +    /// Resolves successor for current case.
>>> +    BasicBlockTy *getCaseSuccessor() {
>>> +      assert((Index < SI->getNumCases() ||
>>> +              Index == DefaultPseudoIndex) &&
>>> +             "Index out the number of cases.");
>>> +      return SI->getSuccessor(getSuccessorIndex());
>>> +    }
>>> +
>>> +    /// Returns number of current case.
>>> +    unsigned getCaseIndex() const { return Index; }
>>> +
>>> +    /// Returns TerminatorInst's successor index for current case successor.
>>> +    unsigned getSuccessorIndex() const {
>>> +      assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
>>> +             "Index out the number of cases.");
>>> +      return Index != DefaultPseudoIndex ? Index + 1 : 0;
>>> +    }
>>> +
>>> +    Self operator++() {
>>> +      // Check index correctness after increment.
>>> +      // Note: Index == getNumCases() means end().
>>> +      assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
>>> +      ++Index;
>>> +      return *this;
>>> +    }
>>> +    Self operator++(int) {
>>> +      Self tmp = *this;
>>> +      ++(*this);
>>> +      return tmp;
>>> +    }
>>> +    Self operator--() {
>>> +      // Check index correctness after decrement.
>>> +      // Note: Index == getNumCases() means end().
>>> +      // Also allow "-1" iterator here. That will became valid after ++.
>>> +      assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
>>> +             "Index out the number of cases.");
>>> +      --Index;
>>> +      return *this;
>>> +    }
>>> +    Self operator--(int) {
>>> +      Self tmp = *this;
>>> +      --(*this);
>>> +      return tmp;
>>> +    }
>>> +    bool operator==(const Self& RHS) const {
>>> +      assert(RHS.SI == SI && "Incompatible operators.");
>>> +      return RHS.Index == Index;
>>> +    }
>>> +    bool operator!=(const Self& RHS) const {
>>> +      assert(RHS.SI == SI && "Incompatible operators.");
>>> +      return RHS.Index != Index;
>>> +    }
>>> +  };
>>> +
>>> +  typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
>>> +    ConstCaseIt;
>>> +
>>> +  class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
>>> +
>>> +    typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
>>> +
>>> +  public:
>>> +
>>> +    CaseIt(const ParentTy& Src) : ParentTy(Src) {}
>>> +    CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
>>> +
>>> +    /// Sets the new value for current case.
>>> +    void setValue(ConstantInt *V) {
>>> +      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> +      SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
>>> +    }
>>> +
>>> +    /// Sets the new successor for current case.
>>> +    void setSuccessor(BasicBlock *S) {
>>> +      SI->setSuccessor(getSuccessorIndex(), S);
>>> +    }
>>> +  };
>>> +
>>>   static SwitchInst *Create(Value *Value, BasicBlock *Default,
>>>                             unsigned NumCases, Instruction *InsertBefore = 0) {
>>>     return new SwitchInst(Value, Default, NumCases, InsertBefore);
>>> @@ -2560,23 +2633,23 @@ public:
>>>   /// Returns a read/write iterator that points to the first
>>>   /// case in SwitchInst.
>>>   CaseIt case_begin() {
>>> -    return CaseIt(this, 0, TheSubsets.begin());
>>> +    return CaseIt(this, 0);
>>>   }
>>>   /// Returns a read-only iterator that points to the first
>>>   /// case in the SwitchInst.
>>>   ConstCaseIt case_begin() const {
>>> -    return ConstCaseIt(this, 0, TheSubsets.begin());
>>> +    return ConstCaseIt(this, 0);
>>>   }
>>> 
>>>   /// Returns a read/write iterator that points one past the last
>>>   /// in the SwitchInst.
>>>   CaseIt case_end() {
>>> -    return CaseIt(this, getNumCases(), TheSubsets.end());
>>> +    return CaseIt(this, getNumCases());
>>>   }
>>>   /// Returns a read-only iterator that points one past the last
>>>   /// in the SwitchInst.
>>>   ConstCaseIt case_end() const {
>>> -    return ConstCaseIt(this, getNumCases(), TheSubsets.end());
>>> +    return ConstCaseIt(this, getNumCases());
>>>   }
>>>   /// Returns an iterator that points to the default case.
>>>   /// Note: this iterator allows to resolve successor only. Attempt
>>> @@ -2584,10 +2657,10 @@ public:
>>>   /// Also note, that increment and decrement also causes an assertion and
>>>   /// makes iterator invalid.
>>>   CaseIt case_default() {
>>> -    return CaseIt(this, DefaultPseudoIndex, TheSubsets.end());
>>> +    return CaseIt(this, DefaultPseudoIndex);
>>>   }
>>>   ConstCaseIt case_default() const {
>>> -    return ConstCaseIt(this, DefaultPseudoIndex, TheSubsets.end());
>>> +    return ConstCaseIt(this, DefaultPseudoIndex);
>>>   }
>>> 
>>>   /// findCaseValue - Search all of the case values for the specified constant.
>>> @@ -2596,13 +2669,13 @@ public:
>>>   /// that it is handled by the default handler.
>>>   CaseIt findCaseValue(const ConstantInt *C) {
>>>     for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
>>> -      if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
>>> +      if (i.getCaseValue() == C)
>>>         return i;
>>>     return case_default();
>>>   }
>>>   ConstCaseIt findCaseValue(const ConstantInt *C) const {
>>>     for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
>>> -      if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
>>> +      if (i.getCaseValue() == C)
>>>         return i;
>>>     return case_default();
>>>   }
>>> @@ -2628,19 +2701,13 @@ public:
>>>   /// point to the added case.
>>>   void addCase(ConstantInt *OnVal, BasicBlock *Dest);
>>> 
>>> -  /// addCase - Add an entry to the switch instruction.
>>> -  /// Note:
>>> -  /// This action invalidates case_end(). Old case_end() iterator will
>>> -  /// point to the added case.
>>> -  void addCase(IntegersSubset& OnVal, BasicBlock *Dest);
>>> -
>>>   /// removeCase - This method removes the specified case and its successor
>>>   /// from the switch instruction. Note that this operation may reorder the
>>>   /// remaining cases at index idx and above.
>>>   /// Note:
>>>   /// This action invalidates iterators for all cases following the one removed,
>>>   /// including the case_end() iterator.
>>> -  void removeCase(CaseIt& i);
>>> +  void removeCase(CaseIt i);
>>> 
>>>   unsigned getNumSuccessors() const { return getNumOperands()/2; }
>>>   BasicBlock *getSuccessor(unsigned idx) const {
>>> @@ -2652,190 +2719,7 @@ public:
>>>     setOperand(idx*2+1, (Value*)NewSucc);
>>>   }
>>> 
>>> -  uint16_t hash() const {
>>> -    uint32_t NumberOfCases = (uint32_t)getNumCases();
>>> -    uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
>>> -    for (ConstCaseIt i = case_begin(), e = case_end();
>>> -         i != e; ++i) {
>>> -      uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
>>> -      Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
>>> -    }
>>> -    return Hash;
>>> -  }
>>> -
>>> -  // Case iterators definition.
>>> -
>>> -  template <class SwitchInstTy, class ConstantIntTy,
>>> -            class SubsetsItTy, class BasicBlockTy>
>>> -  class CaseIteratorT {
>>> -  protected:
>>> -
>>> -    SwitchInstTy *SI;
>>> -    unsigned Index;
>>> -    SubsetsItTy SubsetIt;
>>> -
>>> -    /// Initializes case iterator for given SwitchInst and for given
>>> -    /// case number.
>>> -    friend class SwitchInst;
>>> -    CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex,
>>> -                  SubsetsItTy CaseValueIt) {
>>> -      this->SI = SI;
>>> -      Index = SuccessorIndex;
>>> -      this->SubsetIt = CaseValueIt;
>>> -    }
>>> -
>>> -  public:
>>> -    typedef typename SubsetsItTy::reference IntegersSubsetRef;
>>> -    typedef CaseIteratorT<SwitchInstTy, ConstantIntTy,
>>> -                          SubsetsItTy, BasicBlockTy> Self;
>>> -
>>> -    CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
>>> -          this->SI = SI;
>>> -          Index = CaseNum;
>>> -          SubsetIt = SI->TheSubsets.begin();
>>> -          std::advance(SubsetIt, CaseNum);
>>> -        }
>>> -
>>> -
>>> -    /// Initializes case iterator for given SwitchInst and for given
>>> -    /// TerminatorInst's successor index.
>>> -    static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
>>> -      assert(SuccessorIndex < SI->getNumSuccessors() &&
>>> -             "Successor index # out of range!");
>>> -      return SuccessorIndex != 0 ?
>>> -             Self(SI, SuccessorIndex - 1) :
>>> -             Self(SI, DefaultPseudoIndex);
>>> -    }
>>> -
>>> -    /// Resolves case value for current case.
>>> -    ConstantIntTy *getCaseValue() {
>>> -      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> -      IntegersSubsetRef CaseRanges = *SubsetIt;
>>> -
>>> -      // FIXME: Currently we work with ConstantInt based cases.
>>> -      // So return CaseValue as ConstantInt.
>>> -      return CaseRanges.getSingleNumber(0).toConstantInt();
>>> -    }
>>> -
>>> -    /// Resolves case value for current case.
>>> -    IntegersSubsetRef getCaseValueEx() {
>>> -      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> -      return *SubsetIt;
>>> -    }
>>> -
>>> -    /// Resolves successor for current case.
>>> -    BasicBlockTy *getCaseSuccessor() {
>>> -      assert((Index < SI->getNumCases() ||
>>> -              Index == DefaultPseudoIndex) &&
>>> -             "Index out the number of cases.");
>>> -      return SI->getSuccessor(getSuccessorIndex());
>>> -    }
>>> -
>>> -    /// Returns number of current case.
>>> -    unsigned getCaseIndex() const { return Index; }
>>> -
>>> -    /// Returns TerminatorInst's successor index for current case successor.
>>> -    unsigned getSuccessorIndex() const {
>>> -      assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
>>> -             "Index out the number of cases.");
>>> -      return Index != DefaultPseudoIndex ? Index + 1 : 0;
>>> -    }
>>> -
>>> -    Self operator++() {
>>> -      // Check index correctness after increment.
>>> -      // Note: Index == getNumCases() means end().
>>> -      assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
>>> -      ++Index;
>>> -      if (Index == 0)
>>> -        SubsetIt = SI->TheSubsets.begin();
>>> -      else
>>> -        ++SubsetIt;
>>> -      return *this;
>>> -    }
>>> -    Self operator++(int) {
>>> -      Self tmp = *this;
>>> -      ++(*this);
>>> -      return tmp;
>>> -    }
>>> -    Self operator--() {
>>> -      // Check index correctness after decrement.
>>> -      // Note: Index == getNumCases() means end().
>>> -      // Also allow "-1" iterator here. That will became valid after ++.
>>> -      unsigned NumCases = SI->getNumCases();
>>> -      assert((Index == 0 || Index-1 <= NumCases) &&
>>> -             "Index out the number of cases.");
>>> -      --Index;
>>> -      if (Index == NumCases) {
>>> -        SubsetIt = SI->TheSubsets.end();
>>> -        return *this;
>>> -      }
>>> -
>>> -      if (Index != -1U)
>>> -        --SubsetIt;
>>> -
>>> -      return *this;
>>> -    }
>>> -    Self operator--(int) {
>>> -      Self tmp = *this;
>>> -      --(*this);
>>> -      return tmp;
>>> -    }
>>> -    bool operator==(const Self& RHS) const {
>>> -      assert(RHS.SI == SI && "Incompatible operators.");
>>> -      return RHS.Index == Index;
>>> -    }
>>> -    bool operator!=(const Self& RHS) const {
>>> -      assert(RHS.SI == SI && "Incompatible operators.");
>>> -      return RHS.Index != Index;
>>> -    }
>>> -  };
>>> -
>>> -  class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt,
>>> -                                      SubsetsIt, BasicBlock> {
>>> -    typedef CaseIteratorT<SwitchInst, ConstantInt, SubsetsIt, BasicBlock>
>>> -      ParentTy;
>>> -
>>> -  protected:
>>> -    friend class SwitchInst;
>>> -    CaseIt(SwitchInst *SI, unsigned CaseNum, SubsetsIt SubsetIt) :
>>> -      ParentTy(SI, CaseNum, SubsetIt) {}
>>> -
>>> -    void updateCaseValueOperand(IntegersSubset& V) {
>>> -      SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V));
>>> -    }
>>> -
>>> -  public:
>>> -
>>> -    CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
>>> -
>>> -    CaseIt(const ParentTy& Src) : ParentTy(Src) {}
>>> -
>>> -    /// Sets the new value for current case.
>>> -    void setValue(ConstantInt *V) {
>>> -      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> -      IntegersSubsetToBB Mapping;
>>> -      // FIXME: Currently we work with ConstantInt based cases.
>>> -      // So inititalize IntItem container directly from ConstantInt.
>>> -      Mapping.add(IntItem::fromConstantInt(V));
>>> -      *SubsetIt = Mapping.getCase();
>>> -      updateCaseValueOperand(*SubsetIt);
>>> -    }
>>> -
>>> -    /// Sets the new value for current case.
>>> -    void setValueEx(IntegersSubset& V) {
>>> -      assert(Index < SI->getNumCases() && "Index out the number of cases.");
>>> -      *SubsetIt = V;
>>> -      updateCaseValueOperand(*SubsetIt);
>>> -    }
>>> -
>>> -    /// Sets the new successor for current case.
>>> -    void setSuccessor(BasicBlock *S) {
>>> -      SI->setSuccessor(getSuccessorIndex(), S);
>>> -    }
>>> -  };
>>> -
>>>   // Methods for support type inquiry through isa, cast, and dyn_cast:
>>> -
>>>   static inline bool classof(const Instruction *I) {
>>>     return I->getOpcode() == Instruction::Switch;
>>>   }
>>> 
>>> Removed: llvm/trunk/include/llvm/Support/IntegersSubset.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubset.h?rev=190327&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/IntegersSubset.h (original)
>>> +++ llvm/trunk/include/llvm/Support/IntegersSubset.h (removed)
>>> @@ -1,540 +0,0 @@
>>> -//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
>>> -//
>>> -//                     The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -//
>>> -/// @file
>>> -/// This file contains class that implements constant set of ranges:
>>> -/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
>>> -/// SwitchInst and was used for case value representation that may contain
>>> -/// multiple ranges for a single successor.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
>>> -#define LLVM_SUPPORT_INTEGERSSUBSET_H
>>> -
>>> -#include "llvm/IR/Constants.h"
>>> -#include "llvm/IR/DerivedTypes.h"
>>> -#include "llvm/IR/LLVMContext.h"
>>> -#include <list>
>>> -
>>> -namespace llvm {
>>> -
>>> -  // The IntItem is a wrapper for APInt.
>>> -  // 1. It determines sign of integer, it allows to use
>>> -  //    comparison operators >,<,>=,<=, and as result we got shorter and cleaner
>>> -  //    constructions.
>>> -  // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
>>> -  // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
>>> -  //    It allows to provide SwitchInst methods that works with ConstantInt for
>>> -  //    non-updated passes. And it allows to use APInt interface for new methods.
>>> -  // 4. IntItem can be easily replaced with APInt.
>>> -
>>> -  // The set of macros that allows to propagate APInt operators to the IntItem.
>>> -
>>> -#define INT_ITEM_DEFINE_COMPARISON(op,func) \
>>> -  bool operator op (const APInt& RHS) const { \
>>> -    return getAPIntValue().func(RHS); \
>>> -  }
>>> -
>>> -#define INT_ITEM_DEFINE_UNARY_OP(op) \
>>> -  IntItem operator op () const { \
>>> -    APInt res = op(getAPIntValue()); \
>>> -    Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
>>> -    return IntItem(cast<ConstantInt>(NewVal)); \
>>> -  }
>>> -
>>> -#define INT_ITEM_DEFINE_BINARY_OP(op) \
>>> -  IntItem operator op (const APInt& RHS) const { \
>>> -    APInt res = getAPIntValue() op RHS; \
>>> -    Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
>>> -    return IntItem(cast<ConstantInt>(NewVal)); \
>>> -  }
>>> -
>>> -#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
>>> -  IntItem& operator op (const APInt& RHS) {\
>>> -    APInt res = getAPIntValue();\
>>> -    res op RHS; \
>>> -    Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
>>> -    ConstantIntVal = cast<ConstantInt>(NewVal); \
>>> -    return *this; \
>>> -  }
>>> -
>>> -#define INT_ITEM_DEFINE_PREINCDEC(op) \
>>> -    IntItem& operator op () { \
>>> -      APInt res = getAPIntValue(); \
>>> -      op(res); \
>>> -      Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
>>> -      ConstantIntVal = cast<ConstantInt>(NewVal); \
>>> -      return *this; \
>>> -    }
>>> -
>>> -#define INT_ITEM_DEFINE_POSTINCDEC(op) \
>>> -    IntItem& operator op (int) { \
>>> -      APInt res = getAPIntValue();\
>>> -      op(res); \
>>> -      Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
>>> -      OldConstantIntVal = ConstantIntVal; \
>>> -      ConstantIntVal = cast<ConstantInt>(NewVal); \
>>> -      return IntItem(OldConstantIntVal); \
>>> -    }
>>> -
>>> -#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
>>> -  RetTy operator op (IntTy RHS) const { \
>>> -    return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
>>> -  }
>>> -
>>> -class IntItem {
>>> -  ConstantInt *ConstantIntVal;
>>> -  const APInt* APIntVal;
>>> -  IntItem(const ConstantInt *V) :
>>> -    ConstantIntVal(const_cast<ConstantInt*>(V)),
>>> -    APIntVal(&ConstantIntVal->getValue()){}
>>> -  const APInt& getAPIntValue() const {
>>> -    return *APIntVal;
>>> -  }
>>> -public:
>>> -
>>> -  IntItem() {}
>>> -
>>> -  operator const APInt&() const {
>>> -    return getAPIntValue();
>>> -  }
>>> -
>>> -  // Propagate APInt operators.
>>> -  // Note, that
>>> -  // /,/=,>>,>>= are not implemented in APInt.
>>> -  // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
>>> -
>>> -  INT_ITEM_DEFINE_COMPARISON(<, ult)
>>> -  INT_ITEM_DEFINE_COMPARISON(>, ugt)
>>> -  INT_ITEM_DEFINE_COMPARISON(<=, ule)
>>> -  INT_ITEM_DEFINE_COMPARISON(>=, uge)
>>> -
>>> -  INT_ITEM_DEFINE_COMPARISON(==, eq)
>>> -  INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
>>> -
>>> -  INT_ITEM_DEFINE_COMPARISON(!=, ne)
>>> -  INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
>>> -
>>> -  INT_ITEM_DEFINE_BINARY_OP(*)
>>> -  INT_ITEM_DEFINE_BINARY_OP(+)
>>> -  INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
>>> -  INT_ITEM_DEFINE_BINARY_OP(-)
>>> -  INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
>>> -  INT_ITEM_DEFINE_BINARY_OP(<<)
>>> -  INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
>>> -  INT_ITEM_DEFINE_BINARY_OP(&)
>>> -  INT_ITEM_DEFINE_BINARY_OP(^)
>>> -  INT_ITEM_DEFINE_BINARY_OP(|)
>>> -
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
>>> -  INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
>>> -
>>> -  // Special case for <<=
>>> -  IntItem& operator <<= (unsigned RHS) {
>>> -    APInt res = getAPIntValue();
>>> -    res <<= RHS;
>>> -    Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
>>> -    ConstantIntVal = cast<ConstantInt>(NewVal);
>>> -    return *this;
>>> -  }
>>> -
>>> -  INT_ITEM_DEFINE_UNARY_OP(-)
>>> -  INT_ITEM_DEFINE_UNARY_OP(~)
>>> -
>>> -  INT_ITEM_DEFINE_PREINCDEC(++)
>>> -  INT_ITEM_DEFINE_PREINCDEC(--)
>>> -
>>> -  // The set of workarounds, since currently we use ConstantInt implemented
>>> -  // integer.
>>> -
>>> -  static IntItem fromConstantInt(const ConstantInt *V) {
>>> -    return IntItem(V);
>>> -  }
>>> -  static IntItem fromType(Type* Ty, const APInt& V) {
>>> -    ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
>>> -    return fromConstantInt(C);
>>> -  }
>>> -  static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
>>> -    ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
>>> -        LikeThis.ConstantIntVal->getContext(), V));
>>> -    return fromConstantInt(C);
>>> -  }
>>> -  ConstantInt *toConstantInt() const {
>>> -    return ConstantIntVal;
>>> -  }
>>> -};
>>> -
>>> -template<class IntType>
>>> -class IntRange {
>>> -protected:
>>> -    IntType Low;
>>> -    IntType High;
>>> -    bool IsEmpty : 1;
>>> -    bool IsSingleNumber : 1;
>>> -
>>> -public:
>>> -    typedef IntRange<IntType> self;
>>> -    typedef std::pair<self, self> SubRes;
>>> -
>>> -    IntRange() : IsEmpty(true) {}
>>> -    IntRange(const self &RHS) :
>>> -      Low(RHS.Low), High(RHS.High),
>>> -      IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
>>> -    IntRange(const IntType &C) :
>>> -      Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
>>> -
>>> -    IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
>>> -      IsEmpty(false), IsSingleNumber(Low == High) {}
>>> -
>>> -    bool isEmpty() const { return IsEmpty; }
>>> -    bool isSingleNumber() const { return IsSingleNumber; }
>>> -
>>> -    const IntType& getLow() const {
>>> -      assert(!IsEmpty && "Range is empty.");
>>> -      return Low;
>>> -    }
>>> -    const IntType& getHigh() const {
>>> -      assert(!IsEmpty && "Range is empty.");
>>> -      return High;
>>> -    }
>>> -
>>> -    bool operator<(const self &RHS) const {
>>> -      assert(!IsEmpty && "Left range is empty.");
>>> -      assert(!RHS.IsEmpty && "Right range is empty.");
>>> -      if (Low == RHS.Low) {
>>> -        if (High > RHS.High)
>>> -          return true;
>>> -        return false;
>>> -      }
>>> -      if (Low < RHS.Low)
>>> -        return true;
>>> -      return false;
>>> -    }
>>> -
>>> -    bool operator==(const self &RHS) const {
>>> -      assert(!IsEmpty && "Left range is empty.");
>>> -      assert(!RHS.IsEmpty && "Right range is empty.");
>>> -      return Low == RHS.Low && High == RHS.High;
>>> -    }
>>> -
>>> -    bool operator!=(const self &RHS) const {
>>> -      return !operator ==(RHS);
>>> -    }
>>> -
>>> -    static bool LessBySize(const self &LHS, const self &RHS) {
>>> -      return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
>>> -    }
>>> -
>>> -    bool isInRange(const IntType &IntVal) const {
>>> -      assert(!IsEmpty && "Range is empty.");
>>> -      return IntVal >= Low && IntVal <= High;
>>> -    }
>>> -
>>> -    SubRes sub(const self &RHS) const {
>>> -      SubRes Res;
>>> -
>>> -      // RHS is either more global and includes this range or
>>> -      // if it doesn't intersected with this range.
>>> -      if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
>>> -
>>> -        // If RHS more global (it is enough to check
>>> -        // only one border in this case.
>>> -        if (RHS.isInRange(Low))
>>> -          return std::make_pair(self(Low, High), self());
>>> -
>>> -        return Res;
>>> -      }
>>> -
>>> -      if (Low < RHS.Low) {
>>> -        Res.first.Low = Low;
>>> -        IntType NewHigh = RHS.Low;
>>> -        --NewHigh;
>>> -        Res.first.High = NewHigh;
>>> -      }
>>> -      if (High > RHS.High) {
>>> -        IntType NewLow = RHS.High;
>>> -        ++NewLow;
>>> -        Res.second.Low = NewLow;
>>> -        Res.second.High = High;
>>> -      }
>>> -      return Res;
>>> -    }
>>> -  };
>>> -
>>> -//===----------------------------------------------------------------------===//
>>> -/// IntegersSubsetGeneric - class that implements the subset of integers. It
>>> -/// consists from ranges and single numbers.
>>> -template <class IntTy>
>>> -class IntegersSubsetGeneric {
>>> -public:
>>> -  // Use Chris Lattner idea, that was initially described here:
>>> -  // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
>>> -  // In short, for more compact memory consumption we can store flat
>>> -  // numbers collection, and define range as pair of indices.
>>> -  // In that case we can safe some memory on 32 bit machines.
>>> -  typedef std::vector<IntTy> FlatCollectionTy;
>>> -  typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
>>> -  typedef std::vector<RangeLinkTy> RangeLinksTy;
>>> -  typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
>>> -
>>> -  typedef IntegersSubsetGeneric<IntTy> self;
>>> -
>>> -protected:
>>> -
>>> -  FlatCollectionTy FlatCollection;
>>> -  RangeLinksTy RangeLinks;
>>> -
>>> -  bool IsSingleNumber;
>>> -  bool IsSingleNumbersOnly;
>>> -
>>> -public:
>>> -
>>> -  template<class RangesCollectionTy>
>>> -  explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
>>> -    assert(Links.size() && "Empty ranges are not allowed.");
>>> -
>>> -    // In case of big set of single numbers consumes additional RAM space,
>>> -    // but allows to avoid additional reallocation.
>>> -    FlatCollection.reserve(Links.size() * 2);
>>> -    RangeLinks.reserve(Links.size());
>>> -    IsSingleNumbersOnly = true;
>>> -    for (typename RangesCollectionTy::const_iterator i = Links.begin(),
>>> -         e = Links.end(); i != e; ++i) {
>>> -      RangeLinkTy RangeLink;
>>> -      FlatCollection.push_back(i->getLow());
>>> -      RangeLink.first = &FlatCollection.back();
>>> -      if (i->getLow() != i->getHigh()) {
>>> -        FlatCollection.push_back(i->getHigh());
>>> -        IsSingleNumbersOnly = false;
>>> -      }
>>> -      RangeLink.second = &FlatCollection.back();
>>> -      RangeLinks.push_back(RangeLink);
>>> -    }
>>> -    IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
>>> -  }
>>> -
>>> -  IntegersSubsetGeneric(const self& RHS) {
>>> -    *this = RHS;
>>> -  }
>>> -
>>> -  self& operator=(const self& RHS) {
>>> -    FlatCollection.clear();
>>> -    RangeLinks.clear();
>>> -    FlatCollection.reserve(RHS.RangeLinks.size() * 2);
>>> -    RangeLinks.reserve(RHS.RangeLinks.size());
>>> -    for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
>>> -         i != e; ++i) {
>>> -      RangeLinkTy RangeLink;
>>> -      FlatCollection.push_back(*(i->first));
>>> -      RangeLink.first = &FlatCollection.back();
>>> -      if (i->first != i->second)
>>> -        FlatCollection.push_back(*(i->second));
>>> -      RangeLink.second = &FlatCollection.back();
>>> -      RangeLinks.push_back(RangeLink);
>>> -    }
>>> -    IsSingleNumber = RHS.IsSingleNumber;
>>> -    IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
>>> -    return *this;
>>> -  }
>>> -
>>> -  typedef IntRange<IntTy> Range;
>>> -
>>> -  /// Checks is the given constant satisfies this case. Returns
>>> -  /// true if it equals to one of contained values or belongs to the one of
>>> -  /// contained ranges.
>>> -  bool isSatisfies(const IntTy &CheckingVal) const {
>>> -    if (IsSingleNumber)
>>> -      return FlatCollection.front() == CheckingVal;
>>> -    if (IsSingleNumbersOnly)
>>> -      return std::find(FlatCollection.begin(),
>>> -                       FlatCollection.end(),
>>> -                       CheckingVal) != FlatCollection.end();
>>> -
>>> -    for (size_t i = 0, e = getNumItems(); i < e; ++i) {
>>> -      if (RangeLinks[i].first == RangeLinks[i].second) {
>>> -        if (*RangeLinks[i].first == CheckingVal)
>>> -          return true;
>>> -      } else if (*RangeLinks[i].first <= CheckingVal &&
>>> -                 *RangeLinks[i].second >= CheckingVal)
>>> -        return true;
>>> -    }
>>> -    return false;
>>> -  }
>>> -
>>> -  /// Returns set's item with given index.
>>> -  Range getItem(unsigned idx) const {
>>> -    const RangeLinkTy &Link = RangeLinks[idx];
>>> -    if (Link.first != Link.second)
>>> -      return Range(*Link.first, *Link.second);
>>> -    else
>>> -      return Range(*Link.first);
>>> -  }
>>> -
>>> -  /// Return number of items (ranges) stored in set.
>>> -  size_t getNumItems() const {
>>> -    return RangeLinks.size();
>>> -  }
>>> -
>>> -  /// Returns true if whole subset contains single element.
>>> -  bool isSingleNumber() const {
>>> -    return IsSingleNumber;
>>> -  }
>>> -
>>> -  /// Returns true if whole subset contains only single numbers, no ranges.
>>> -  bool isSingleNumbersOnly() const {
>>> -    return IsSingleNumbersOnly;
>>> -  }
>>> -
>>> -  /// Does the same like getItem(idx).isSingleNumber(), but
>>> -  /// works faster, since we avoid creation of temporary range object.
>>> -  bool isSingleNumber(unsigned idx) const {
>>> -    return RangeLinks[idx].first == RangeLinks[idx].second;
>>> -  }
>>> -
>>> -  /// Returns set the size, that equals number of all values + sizes of all
>>> -  /// ranges.
>>> -  /// Ranges set is considered as flat numbers collection.
>>> -  /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
>>> -  ///       for range [<0>, <1>, <5>] the size will 3
>>> -  unsigned getSize() const {
>>> -    APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
>>> -    for (size_t i = 0, e = getNumItems(); i != e; ++i) {
>>> -      const APInt Low = getItem(i).getLow();
>>> -      const APInt High = getItem(i).getHigh();
>>> -      APInt S = High - Low + 1;
>>> -      sz += S;
>>> -    }
>>> -    return sz.getZExtValue();
>>> -  }
>>> -
>>> -  /// Allows to access single value even if it belongs to some range.
>>> -  /// Ranges set is considered as flat numbers collection.
>>> -  /// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
>>> -  /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
>>> -  APInt getSingleValue(unsigned idx) const {
>>> -    APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
>>> -    for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
>>> -      const APInt Low = getItem(i).getLow();
>>> -      const APInt High = getItem(i).getHigh();
>>> -      APInt S = High - Low + 1;
>>> -      APInt oldSz = sz;
>>> -      sz += S;
>>> -      if (sz.ugt(idx)) {
>>> -        APInt Res = Low;
>>> -        APInt Offset(oldSz.getBitWidth(), idx);
>>> -        Offset -= oldSz;
>>> -        Res += Offset;
>>> -        return Res;
>>> -      }
>>> -    }
>>> -    assert(0 && "Index exceeds high border.");
>>> -    return sz;
>>> -  }
>>> -
>>> -  /// Does the same as getSingleValue, but works only if subset contains
>>> -  /// single numbers only.
>>> -  const IntTy& getSingleNumber(unsigned idx) const {
>>> -    assert(IsSingleNumbersOnly && "This method works properly if subset "
>>> -                                  "contains single numbers only.");
>>> -    return FlatCollection[idx];
>>> -  }
>>> -};
>>> -
>>> -//===----------------------------------------------------------------------===//
>>> -/// IntegersSubset - currently is extension of IntegersSubsetGeneric
>>> -/// that also supports conversion to/from Constant* object.
>>> -class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
>>> -
>>> -  typedef IntegersSubsetGeneric<IntItem> ParentTy;
>>> -
>>> -  Constant *Holder;
>>> -
>>> -  static unsigned getNumItemsFromConstant(Constant *C) {
>>> -    return cast<ArrayType>(C->getType())->getNumElements();
>>> -  }
>>> -
>>> -  static Range getItemFromConstant(Constant *C, unsigned idx) {
>>> -    const Constant *CV = C->getAggregateElement(idx);
>>> -
>>> -    unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
>>> -    switch (NumEls) {
>>> -    case 1:
>>> -      return Range(IntItem::fromConstantInt(
>>> -                     cast<ConstantInt>(CV->getAggregateElement(0U))),
>>> -                   IntItem::fromConstantInt(cast<ConstantInt>(
>>> -                     cast<ConstantInt>(CV->getAggregateElement(0U)))));
>>> -    case 2:
>>> -      return Range(IntItem::fromConstantInt(
>>> -                     cast<ConstantInt>(CV->getAggregateElement(0U))),
>>> -                   IntItem::fromConstantInt(
>>> -                   cast<ConstantInt>(CV->getAggregateElement(1))));
>>> -    default:
>>> -      assert(0 && "Only pairs and single numbers are allowed here.");
>>> -      return Range();
>>> -    }
>>> -  }
>>> -
>>> -  std::vector<Range> rangesFromConstant(Constant *C) {
>>> -    unsigned NumItems = getNumItemsFromConstant(C);
>>> -    std::vector<Range> r;
>>> -    r.reserve(NumItems);
>>> -    for (unsigned i = 0, e = NumItems; i != e; ++i)
>>> -      r.push_back(getItemFromConstant(C, i));
>>> -    return r;
>>> -  }
>>> -
>>> -public:
>>> -
>>> -  explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
>>> -                          Holder(C) {}
>>> -
>>> -  IntegersSubset(const IntegersSubset& RHS) :
>>> -    ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
>>> -    Holder(RHS.Holder) {}
>>> -
>>> -  template<class RangesCollectionTy>
>>> -  explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
>>> -    std::vector<Constant*> Elts;
>>> -    Elts.reserve(Src.size());
>>> -    for (typename RangesCollectionTy::const_iterator i = Src.begin(),
>>> -         e = Src.end(); i != e; ++i) {
>>> -      const Range &R = *i;
>>> -      std::vector<Constant*> r;
>>> -      if (R.isSingleNumber()) {
>>> -        r.reserve(2);
>>> -        // FIXME: Since currently we have ConstantInt based numbers
>>> -        // use hack-conversion of IntItem to ConstantInt
>>> -        r.push_back(R.getLow().toConstantInt());
>>> -        r.push_back(R.getHigh().toConstantInt());
>>> -      } else {
>>> -        r.reserve(1);
>>> -        r.push_back(R.getLow().toConstantInt());
>>> -      }
>>> -      Constant *CV = ConstantVector::get(r);
>>> -      Elts.push_back(CV);
>>> -    }
>>> -    ArrayType *ArrTy =
>>> -        ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
>>> -    Holder = ConstantArray::get(ArrTy, Elts);
>>> -  }
>>> -
>>> -  operator Constant*() { return Holder; }
>>> -  operator const Constant*() const { return Holder; }
>>> -  Constant *operator->() { return Holder; }
>>> -  const Constant *operator->() const { return Holder; }
>>> -};
>>> -
>>> -}
>>> -
>>> -#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
>>> 
>>> Removed: llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h?rev=190327&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h (original)
>>> +++ llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h (removed)
>>> @@ -1,588 +0,0 @@
>>> -//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
>>> -//
>>> -//                     The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -//
>>> -/// @file
>>> -/// IntegersSubsetMapping is mapping from A to B, where
>>> -/// Items in A is subsets of integers,
>>> -/// Items in B some pointers (Successors).
>>> -/// If user which to add another subset for successor that is already
>>> -/// exists in mapping, IntegersSubsetMapping merges existing subset with
>>> -/// added one.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
>>> -#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
>>> -
>>> -#include "llvm/Support/IntegersSubset.h"
>>> -#include <list>
>>> -#include <map>
>>> -#include <vector>
>>> -
>>> -namespace llvm {
>>> -
>>> -template <class SuccessorClass,
>>> -          class IntegersSubsetTy = IntegersSubset,
>>> -          class IntTy = IntItem>
>>> -class IntegersSubsetMapping {
>>> -  // FIXME: To much similar iterators typedefs, similar names.
>>> -  //        - Rename RangeIterator to the cluster iterator.
>>> -  //        - Remove unused "add" methods.
>>> -  //        - Class contents needs cleaning.
>>> -public:
>>> -
>>> -  typedef IntRange<IntTy> RangeTy;
>>> -
>>> -  struct RangeEx : public RangeTy {
>>> -    RangeEx() : Weight(1) {}
>>> -    RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
>>> -    RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
>>> -    RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
>>> -    RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
>>> -    RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
>>> -      RangeTy(L, H), Weight(W) {}
>>> -    unsigned Weight;
>>> -  };
>>> -
>>> -  typedef std::pair<RangeEx, SuccessorClass*> Cluster;
>>> -
>>> -  typedef std::list<RangeTy> RangesCollection;
>>> -  typedef typename RangesCollection::iterator RangesCollectionIt;
>>> -  typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
>>> -  typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
>>> -
>>> -protected:
>>> -
>>> -  typedef std::list<Cluster> CaseItems;
>>> -  typedef typename CaseItems::iterator CaseItemIt;
>>> -  typedef typename CaseItems::const_iterator CaseItemConstIt;
>>> -
>>> -  // TODO: Change unclean CRS prefixes to SubsetMap for example.
>>> -  typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
>>> -  typedef typename CRSMap::iterator CRSMapIt;
>>> -
>>> -  struct ClustersCmp {
>>> -    bool operator()(const Cluster &C1, const Cluster &C2) {
>>> -      return C1.first < C2.first;
>>> -    }
>>> -  };
>>> -
>>> -  CaseItems Items;
>>> -  bool Sorted;
>>> -
>>> -  bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
>>> -    return LItem->first.getHigh() >= RItem->first.getLow();
>>> -  }
>>> -
>>> -  bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
>>> -    if (LItem->second != RItem->second) {
>>> -      assert(!isIntersected(LItem, RItem) &&
>>> -             "Intersected items with different successors!");
>>> -      return false;
>>> -    }
>>> -    APInt RLow = RItem->first.getLow();
>>> -    if (RLow != APInt::getNullValue(RLow.getBitWidth()))
>>> -      --RLow;
>>> -    return LItem->first.getHigh() >= RLow;
>>> -  }
>>> -
>>> -  void sort() {
>>> -    if (!Sorted) {
>>> -      std::vector<Cluster> clustersVector;
>>> -      clustersVector.reserve(Items.size());
>>> -      clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
>>> -      std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
>>> -      Items.clear();
>>> -      Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
>>> -      Sorted = true;
>>> -    }
>>> -  }
>>> -
>>> -  enum DiffProcessState {
>>> -    L_OPENED,
>>> -    INTERSECT_OPENED,
>>> -    R_OPENED,
>>> -    ALL_IS_CLOSED
>>> -  };
>>> -
>>> -  class DiffStateMachine {
>>> -
>>> -    DiffProcessState State;
>>> -    IntTy OpenPt;
>>> -    SuccessorClass *CurrentLSuccessor;
>>> -    SuccessorClass *CurrentRSuccessor;
>>> -
>>> -    self *LeftMapping;
>>> -    self *IntersectionMapping;
>>> -    self *RightMapping;
>>> -
>>> -  public:
>>> -
>>> -    typedef
>>> -      IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
>>> -
>>> -    DiffStateMachine(MappingTy *L,
>>> -                                 MappingTy *Intersection,
>>> -                                 MappingTy *R) :
>>> -                                 State(ALL_IS_CLOSED),
>>> -                                 LeftMapping(L),
>>> -                                 IntersectionMapping(Intersection),
>>> -                                 RightMapping(R)
>>> -                                 {}
>>> -
>>> -    void onLOpen(const IntTy &Pt, SuccessorClass *S) {
>>> -      switch (State) {
>>> -      case R_OPENED:
>>> -        if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
>>> -          RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
>>> -        State = INTERSECT_OPENED;
>>> -        break;
>>> -      case ALL_IS_CLOSED:
>>> -        State = L_OPENED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -      CurrentLSuccessor = S;
>>> -      OpenPt = Pt;
>>> -    }
>>> -
>>> -    void onLClose(const IntTy &Pt) {
>>> -      switch (State) {
>>> -      case L_OPENED:
>>> -        assert(Pt >= OpenPt &&
>>> -               "Subset is not sorted or contains overlapped ranges");
>>> -        if (LeftMapping)
>>> -          LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
>>> -        State = ALL_IS_CLOSED;
>>> -        break;
>>> -      case INTERSECT_OPENED:
>>> -        if (IntersectionMapping)
>>> -          IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
>>> -        OpenPt = Pt + 1;
>>> -        State = R_OPENED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -    }
>>> -
>>> -    void onROpen(const IntTy &Pt, SuccessorClass *S) {
>>> -      switch (State) {
>>> -      case L_OPENED:
>>> -        if (Pt > OpenPt && LeftMapping)
>>> -          LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
>>> -        State = INTERSECT_OPENED;
>>> -        break;
>>> -      case ALL_IS_CLOSED:
>>> -        State = R_OPENED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -      CurrentRSuccessor = S;
>>> -      OpenPt = Pt;
>>> -    }
>>> -
>>> -    void onRClose(const IntTy &Pt) {
>>> -      switch (State) {
>>> -      case R_OPENED:
>>> -        assert(Pt >= OpenPt &&
>>> -               "Subset is not sorted or contains overlapped ranges");
>>> -        if (RightMapping)
>>> -          RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
>>> -        State = ALL_IS_CLOSED;
>>> -        break;
>>> -      case INTERSECT_OPENED:
>>> -        if (IntersectionMapping)
>>> -          IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
>>> -        OpenPt = Pt + 1;
>>> -        State = L_OPENED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -    }
>>> -
>>> -    void onLROpen(const IntTy &Pt,
>>> -                  SuccessorClass *LS,
>>> -                  SuccessorClass *RS) {
>>> -      switch (State) {
>>> -      case ALL_IS_CLOSED:
>>> -        State = INTERSECT_OPENED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -      CurrentLSuccessor = LS;
>>> -      CurrentRSuccessor = RS;
>>> -      OpenPt = Pt;
>>> -    }
>>> -
>>> -    void onLRClose(const IntTy &Pt) {
>>> -      switch (State) {
>>> -      case INTERSECT_OPENED:
>>> -        if (IntersectionMapping)
>>> -          IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
>>> -        State = ALL_IS_CLOSED;
>>> -        break;
>>> -      default:
>>> -        assert(0 && "Got unexpected point.");
>>> -        break;
>>> -      }
>>> -    }
>>> -
>>> -    bool isLOpened() { return State == L_OPENED; }
>>> -    bool isROpened() { return State == R_OPENED; }
>>> -  };
>>> -
>>> -public:
>>> -
>>> -  // Don't public CaseItems itself. Don't allow edit the Items directly.
>>> -  // Just present the user way to iterate over the internal collection
>>> -  // sharing iterator, begin() and end(). Editing should be controlled by
>>> -  // factory.
>>> -  typedef CaseItemIt RangeIterator;
>>> -
>>> -  typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
>>> -  typedef std::list<Case> Cases;
>>> -  typedef typename Cases::iterator CasesIt;
>>> -
>>> -  IntegersSubsetMapping() {
>>> -    Sorted = false;
>>> -  }
>>> -
>>> -  bool verify() {
>>> -    RangeIterator DummyErrItem;
>>> -    return verify(DummyErrItem);
>>> -  }
>>> -
>>> -  bool verify(RangeIterator& errItem) {
>>> -    if (Items.empty())
>>> -      return true;
>>> -    sort();
>>> -    for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
>>> -         j != e; i = j++) {
>>> -      if (isIntersected(i, j) && i->second != j->second) {
>>> -        errItem = j;
>>> -        return false;
>>> -      }
>>> -    }
>>> -    return true;
>>> -  }
>>> -
>>> -  bool isOverlapped(self &RHS) {
>>> -    if (Items.empty() || RHS.empty())
>>> -      return true;
>>> -
>>> -    for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
>>> -         el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
>>> -
>>> -      const RangeTy &LRange = L->first;
>>> -      const RangeTy &RRange = R->first;
>>> -
>>> -      if (LRange.getLow() > RRange.getLow()) {
>>> -        if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
>>> -          ++R;
>>> -        else
>>> -          return true;
>>> -      } else if (LRange.getLow() < RRange.getLow()) {
>>> -        if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
>>> -          ++L;
>>> -        else
>>> -          return true;
>>> -      } else // iRange.getLow() == jRange.getLow()
>>> -        return true;
>>> -    }
>>> -    return false;
>>> -  }
>>> -
>>> -
>>> -  void optimize() {
>>> -    if (Items.size() < 2)
>>> -      return;
>>> -    sort();
>>> -    CaseItems OldItems = Items;
>>> -    Items.clear();
>>> -    const IntTy *Low = &OldItems.begin()->first.getLow();
>>> -    const IntTy *High = &OldItems.begin()->first.getHigh();
>>> -    unsigned Weight = OldItems.begin()->first.Weight;
>>> -    SuccessorClass *Successor = OldItems.begin()->second;
>>> -    for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
>>> -         j != e; i = j++) {
>>> -      if (isJoinable(i, j)) {
>>> -        const IntTy *CurHigh = &j->first.getHigh();
>>> -        Weight += j->first.Weight;
>>> -        if (*CurHigh > *High)
>>> -          High = CurHigh;
>>> -      } else {
>>> -        RangeEx R(*Low, *High, Weight);
>>> -        add(R, Successor);
>>> -        Low = &j->first.getLow();
>>> -        High = &j->first.getHigh();
>>> -        Weight = j->first.Weight;
>>> -        Successor = j->second;
>>> -      }
>>> -    }
>>> -    RangeEx R(*Low, *High, Weight);
>>> -    add(R, Successor);
>>> -    // We recollected the Items, but we kept it sorted.
>>> -    Sorted = true;
>>> -  }
>>> -
>>> -  /// Adds a constant value.
>>> -  void add(const IntTy &C, SuccessorClass *S = 0) {
>>> -    RangeTy R(C);
>>> -    add(R, S);
>>> -  }
>>> -
>>> -  /// Adds a range.
>>> -  void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
>>> -    RangeTy R(Low, High);
>>> -    add(R, S);
>>> -  }
>>> -  void add(const RangeTy &R, SuccessorClass *S = 0) {
>>> -    RangeEx REx = R;
>>> -    add(REx, S);
>>> -  }
>>> -  void add(const RangeEx &R, SuccessorClass *S = 0) {
>>> -    Items.push_back(std::make_pair(R, S));
>>> -    Sorted = false;
>>> -  }
>>> -
>>> -  /// Adds all ranges and values from given ranges set to the current
>>> -  /// mapping.
>>> -  void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
>>> -           unsigned Weight = 0) {
>>> -    unsigned ItemWeight = 1;
>>> -    if (Weight)
>>> -      // Weight is associated with CRS, for now we perform a division to
>>> -      // get the weight for each item.
>>> -      ItemWeight = Weight / CRS.getNumItems();
>>> -    for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
>>> -      RangeTy R = CRS.getItem(i);
>>> -      RangeEx REx(R, ItemWeight);
>>> -      add(REx, S);
>>> -    }
>>> -  }
>>> -
>>> -  void add(self& RHS) {
>>> -    Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
>>> -  }
>>> -
>>> -  void add(self& RHS, SuccessorClass *S) {
>>> -    for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
>>> -      add(i->first, S);
>>> -  }
>>> -
>>> -  void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
>>> -    for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
>>> -      add(*i, S);
>>> -  }
>>> -
>>> -  /// Removes items from set.
>>> -  void removeItem(RangeIterator i) { Items.erase(i); }
>>> -
>>> -  /// Moves whole case from current mapping to the NewMapping object.
>>> -  void detachCase(self& NewMapping, SuccessorClass *Succ) {
>>> -    for (CaseItemIt i = Items.begin(); i != Items.end();)
>>> -      if (i->second == Succ) {
>>> -        NewMapping.add(i->first, i->second);
>>> -        Items.erase(i++);
>>> -      } else
>>> -        ++i;
>>> -  }
>>> -
>>> -  /// Removes all clusters for given successor.
>>> -  void removeCase(SuccessorClass *Succ) {
>>> -    for (CaseItemIt i = Items.begin(); i != Items.end();)
>>> -      if (i->second == Succ) {
>>> -        Items.erase(i++);
>>> -      } else
>>> -        ++i;
>>> -  }
>>> -
>>> -  /// Find successor that satisfies given value.
>>> -  SuccessorClass *findSuccessor(const IntTy& Val) {
>>> -    for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
>>> -      if (i->first.isInRange(Val))
>>> -        return i->second;
>>> -    }
>>> -    return 0;
>>> -  }
>>> -
>>> -  /// Calculates the difference between this mapping and RHS.
>>> -  /// THIS without RHS is placed into LExclude,
>>> -  /// RHS without THIS is placed into RExclude,
>>> -  /// THIS intersect RHS is placed into Intersection.
>>> -  void diff(self *LExclude, self *Intersection, self *RExclude,
>>> -                             const self& RHS) {
>>> -
>>> -    DiffStateMachine Machine(LExclude, Intersection, RExclude);
>>> -
>>> -    CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
>>> -    while (L != Items.end() && R != RHS.Items.end()) {
>>> -      const Cluster &LCluster = *L;
>>> -      const RangeEx &LRange = LCluster.first;
>>> -      const Cluster &RCluster = *R;
>>> -      const RangeEx &RRange = RCluster.first;
>>> -
>>> -      if (LRange.getHigh() < RRange.getLow()) {
>>> -        Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> -        Machine.onLClose(LRange.getHigh());
>>> -        ++L;
>>> -        continue;
>>> -      }
>>> -
>>> -      if (LRange.getLow() > RRange.getHigh()) {
>>> -        Machine.onROpen(RRange.getLow(), RCluster.second);
>>> -        Machine.onRClose(RRange.getHigh());
>>> -        ++R;
>>> -        continue;
>>> -      }
>>> -
>>> -      if (LRange.getLow() < RRange.getLow()) {
>>> -        // May be opened in previous iteration.
>>> -        if (!Machine.isLOpened())
>>> -          Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> -        Machine.onROpen(RRange.getLow(), RCluster.second);
>>> -      }
>>> -      else if (RRange.getLow() < LRange.getLow()) {
>>> -        if (!Machine.isROpened())
>>> -          Machine.onROpen(RRange.getLow(), RCluster.second);
>>> -        Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> -      }
>>> -      else
>>> -        Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
>>> -
>>> -      if (LRange.getHigh() < RRange.getHigh()) {
>>> -        Machine.onLClose(LRange.getHigh());
>>> -        ++L;
>>> -        while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
>>> -          Machine.onLOpen(L->first.getLow(), L->second);
>>> -          Machine.onLClose(L->first.getHigh());
>>> -          ++L;
>>> -        }
>>> -      }
>>> -      else if (RRange.getHigh() < LRange.getHigh()) {
>>> -        Machine.onRClose(RRange.getHigh());
>>> -        ++R;
>>> -        while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
>>> -          Machine.onROpen(R->first.getLow(), R->second);
>>> -          Machine.onRClose(R->first.getHigh());
>>> -          ++R;
>>> -        }
>>> -      }
>>> -      else {
>>> -        Machine.onLRClose(LRange.getHigh());
>>> -        ++L;
>>> -        ++R;
>>> -      }
>>> -    }
>>> -
>>> -    if (L != Items.end()) {
>>> -      if (Machine.isLOpened()) {
>>> -        Machine.onLClose(L->first.getHigh());
>>> -        ++L;
>>> -      }
>>> -      if (LExclude)
>>> -        while (L != Items.end()) {
>>> -          LExclude->add(L->first, L->second);
>>> -          ++L;
>>> -        }
>>> -    } else if (R != RHS.Items.end()) {
>>> -      if (Machine.isROpened()) {
>>> -        Machine.onRClose(R->first.getHigh());
>>> -        ++R;
>>> -      }
>>> -      if (RExclude)
>>> -        while (R != RHS.Items.end()) {
>>> -          RExclude->add(R->first, R->second);
>>> -          ++R;
>>> -        }
>>> -    }
>>> -  }
>>> -
>>> -  /// Builds the finalized case objects.
>>> -  void getCases(Cases& TheCases, bool PreventMerging = false) {
>>> -    //FIXME: PreventMerging is a temporary parameter.
>>> -    //Currently a set of passes is still knows nothing about
>>> -    //switches with case ranges, and if these passes meet switch
>>> -    //with complex case that crashs the application.
>>> -    if (PreventMerging) {
>>> -      for (RangeIterator i = this->begin(); i != this->end(); ++i) {
>>> -        RangesCollection SingleRange;
>>> -        SingleRange.push_back(i->first);
>>> -        TheCases.push_back(std::make_pair(i->second,
>>> -                                          IntegersSubsetTy(SingleRange)));
>>> -      }
>>> -      return;
>>> -    }
>>> -    CRSMap TheCRSMap;
>>> -    for (RangeIterator i = this->begin(); i != this->end(); ++i)
>>> -      TheCRSMap[i->second].push_back(i->first);
>>> -    for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
>>> -      TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
>>> -  }
>>> -
>>> -  /// Builds the finalized case objects ignoring successor values, as though
>>> -  /// all ranges belongs to the same successor.
>>> -  IntegersSubsetTy getCase() {
>>> -    RangesCollection Ranges;
>>> -    for (RangeIterator i = this->begin(); i != this->end(); ++i)
>>> -      Ranges.push_back(i->first);
>>> -    return IntegersSubsetTy(Ranges);
>>> -  }
>>> -
>>> -  /// Returns pointer to value of case if it is single-numbered or 0
>>> -  /// in another case.
>>> -  const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
>>> -    const IntTy* Res = 0;
>>> -    for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
>>> -      if (i->second == Succ) {
>>> -        if (!i->first.isSingleNumber())
>>> -          return 0;
>>> -        if (Res)
>>> -          return 0;
>>> -        else
>>> -          Res = &(i->first.getLow());
>>> -      }
>>> -    return Res;
>>> -  }
>>> -
>>> -  /// Returns true if there is no ranges and values inside.
>>> -  bool empty() const { return Items.empty(); }
>>> -
>>> -  void clear() {
>>> -    Items.clear();
>>> -    // Don't reset Sorted flag:
>>> -    // 1. For empty mapping it matters nothing.
>>> -    // 2. After first item will added Sorted flag will cleared.
>>> -  }
>>> -
>>> -  // Returns number of clusters
>>> -  unsigned size() const {
>>> -    return Items.size();
>>> -  }
>>> -
>>> -  RangeIterator begin() { return Items.begin(); }
>>> -  RangeIterator end() { return Items.end(); }
>>> -};
>>> -
>>> -class BasicBlock;
>>> -typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
>>> -
>>> -}
>>> -
>>> -#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
>>> 
>>> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
>>> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Sep  9 14:14:35 2013
>>> @@ -2491,7 +2491,10 @@ bool BitcodeReader::ParseFunctionBody(Fu
>>>     case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
>>>       // Check magic
>>>       if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
>>> -        // New SwitchInst format with case ranges.
>>> +        // "New" SwitchInst format with case ranges. The changes to write this
>>> +        // format were reverted but we still recognize bitcode that uses it.
>>> +        // Hopefully someday we will have support for case ranges and can use
>>> +        // this format again.
>>> 
>>>         Type *OpTy = getTypeByID(Record[1]);
>>>         unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
>>> @@ -2508,7 +2511,7 @@ bool BitcodeReader::ParseFunctionBody(Fu
>>> 
>>>         unsigned CurIdx = 5;
>>>         for (unsigned i = 0; i != NumCases; ++i) {
>>> -          IntegersSubsetToBB CaseBuilder;
>>> +          SmallVector<ConstantInt*, 1> CaseVals;
>>>           unsigned NumItems = Record[CurIdx++];
>>>           for (unsigned ci = 0; ci != NumItems; ++ci) {
>>>             bool isSingleNumber = Record[CurIdx++];
>>> @@ -2528,20 +2531,22 @@ bool BitcodeReader::ParseFunctionBody(Fu
>>>               APInt High =
>>>                   ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
>>>                                 ValueBitWidth);
>>> -
>>> -              CaseBuilder.add(IntItem::fromType(OpTy, Low),
>>> -                              IntItem::fromType(OpTy, High));
>>>               CurIdx += ActiveWords;
>>> +
>>> +              // FIXME: It is not clear whether values in the range should be
>>> +              // compared as signed or unsigned values. The partially
>>> +              // implemented changes that used this format in the past used
>>> +              // unsigned comparisons.
>>> +              for ( ; Low.ule(High); ++Low)
>>> +                CaseVals.push_back(ConstantInt::get(Context, Low));
>>>             } else
>>> -              CaseBuilder.add(IntItem::fromType(OpTy, Low));
>>> +              CaseVals.push_back(ConstantInt::get(Context, Low));
>>>           }
>>>           BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
>>> -          IntegersSubset Case = CaseBuilder.getCase();
>>> -          SI->addCase(Case, DestBB);
>>> +          for (SmallVector<ConstantInt*, 1>::iterator cvi = CaseVals.begin(),
>>> +                 cve = CaseVals.end(); cvi != cve; ++cvi)
>>> +            SI->addCase(*cvi, DestBB);
>>>         }
>>> -        uint16_t Hash = SI->hash();
>>> -        if (Hash != (Record[0] & 0xFFFF))
>>> -          return Error("Invalid SWITCH record");
>>>         I = SI;
>>>         break;
>>>       }
>>> 
>>> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
>>> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Sep  9 14:14:35 2013
>>> @@ -60,10 +60,7 @@ enum {
>>>   FUNCTION_INST_CAST_ABBREV,
>>>   FUNCTION_INST_RET_VOID_ABBREV,
>>>   FUNCTION_INST_RET_VAL_ABBREV,
>>> -  FUNCTION_INST_UNREACHABLE_ABBREV,
>>> -
>>> -  // SwitchInst Magic
>>> -  SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
>>> +  FUNCTION_INST_UNREACHABLE_ABBREV
>>> };
>>> 
>>> static unsigned GetEncodedCastOpcode(unsigned Opcode) {
>>> @@ -865,34 +862,6 @@ static void emitSignedInt64(SmallVectorI
>>>     Vals.push_back((-V << 1) | 1);
>>> }
>>> 
>>> -static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals,
>>> -                      unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
>>> -                      bool EmitSizeForWideNumbers = false
>>> -                      ) {
>>> -  if (Val.getBitWidth() <= 64) {
>>> -    uint64_t V = Val.getSExtValue();
>>> -    emitSignedInt64(Vals, V);
>>> -    Code = bitc::CST_CODE_INTEGER;
>>> -    AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
>>> -  } else {
>>> -    // Wide integers, > 64 bits in size.
>>> -    // We have an arbitrary precision integer value to write whose
>>> -    // bit width is > 64. However, in canonical unsigned integer
>>> -    // format it is likely that the high bits are going to be zero.
>>> -    // So, we only write the number of active words.
>>> -    unsigned NWords = Val.getActiveWords();
>>> -
>>> -    if (EmitSizeForWideNumbers)
>>> -      Vals.push_back(NWords);
>>> -
>>> -    const uint64_t *RawWords = Val.getRawData();
>>> -    for (unsigned i = 0; i != NWords; ++i) {
>>> -      emitSignedInt64(Vals, RawWords[i]);
>>> -    }
>>> -    Code = bitc::CST_CODE_WIDE_INTEGER;
>>> -  }
>>> -}
>>> -
>>> static void WriteConstants(unsigned FirstVal, unsigned LastVal,
>>>                            const ValueEnumerator &VE,
>>>                            BitstreamWriter &Stream, bool isGlobal) {
>>> @@ -976,7 +945,23 @@ static void WriteConstants(unsigned Firs
>>>     } else if (isa<UndefValue>(C)) {
>>>       Code = bitc::CST_CODE_UNDEF;
>>>     } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
>>> -      EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
>>> +      if (IV->getBitWidth() <= 64) {
>>> +        uint64_t V = IV->getSExtValue();
>>> +        emitSignedInt64(Record, V);
>>> +        Code = bitc::CST_CODE_INTEGER;
>>> +        AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
>>> +      } else {                             // Wide integers, > 64 bits in size.
>>> +        // We have an arbitrary precision integer value to write whose
>>> +        // bit width is > 64. However, in canonical unsigned integer
>>> +        // format it is likely that the high bits are going to be zero.
>>> +        // So, we only write the number of active words.
>>> +        unsigned NWords = IV->getValue().getActiveWords();
>>> +        const uint64_t *RawWords = IV->getValue().getRawData();
>>> +        for (unsigned i = 0; i != NWords; ++i) {
>>> +          emitSignedInt64(Record, RawWords[i]);
>>> +        }
>>> +        Code = bitc::CST_CODE_WIDE_INTEGER;
>>> +      }
>>>     } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
>>>       Code = bitc::CST_CODE_FLOAT;
>>>       Type *Ty = CFP->getType();
>>> @@ -1184,13 +1169,6 @@ static void pushValue(const Value *V, un
>>>   Vals.push_back(InstID - ValID);
>>> }
>>> 
>>> -static void pushValue64(const Value *V, unsigned InstID,
>>> -                        SmallVectorImpl<uint64_t> &Vals,
>>> -                        ValueEnumerator &VE) {
>>> -  uint64_t ValID = VE.getValueID(V);
>>> -  Vals.push_back(InstID - ValID);
>>> -}
>>> -
>>> static void pushValueSigned(const Value *V, unsigned InstID,
>>>                             SmallVectorImpl<uint64_t> &Vals,
>>>                             ValueEnumerator &VE) {
>>> @@ -1314,63 +1292,16 @@ static void WriteInstruction(const Instr
>>>     break;
>>>   case Instruction::Switch:
>>>     {
>>> -      // Redefine Vals, since here we need to use 64 bit values
>>> -      // explicitly to store large APInt numbers.
>>> -      SmallVector<uint64_t, 128> Vals64;
>>> -
>>>       Code = bitc::FUNC_CODE_INST_SWITCH;
>>>       const SwitchInst &SI = cast<SwitchInst>(I);
>>> -
>>> -      uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
>>> -      Vals64.push_back(SwitchRecordHeader);
>>> -
>>> -      Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
>>> -      pushValue64(SI.getCondition(), InstID, Vals64, VE);
>>> -      Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
>>> -      Vals64.push_back(SI.getNumCases());
>>> +      Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
>>> +      pushValue(SI.getCondition(), InstID, Vals, VE);
>>> +      Vals.push_back(VE.getValueID(SI.getDefaultDest()));
>>>       for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
>>>            i != e; ++i) {
>>> -        const IntegersSubset& CaseRanges = i.getCaseValueEx();
>>> -        unsigned Code, Abbrev; // will unused.
>>> -
>>> -        if (CaseRanges.isSingleNumber()) {
>>> -          Vals64.push_back(1/*NumItems = 1*/);
>>> -          Vals64.push_back(true/*IsSingleNumber = true*/);
>>> -          EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
>>> -        } else {
>>> -
>>> -          Vals64.push_back(CaseRanges.getNumItems());
>>> -
>>> -          if (CaseRanges.isSingleNumbersOnly()) {
>>> -            for (unsigned ri = 0, rn = CaseRanges.getNumItems();
>>> -                 ri != rn; ++ri) {
>>> -
>>> -              Vals64.push_back(true/*IsSingleNumber = true*/);
>>> -
>>> -              EmitAPInt(Vals64, Code, Abbrev,
>>> -                        CaseRanges.getSingleNumber(ri), true);
>>> -            }
>>> -          } else
>>> -            for (unsigned ri = 0, rn = CaseRanges.getNumItems();
>>> -                 ri != rn; ++ri) {
>>> -              IntegersSubset::Range r = CaseRanges.getItem(ri);
>>> -              bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
>>> -
>>> -              Vals64.push_back(IsSingleNumber);
>>> -
>>> -              EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
>>> -              if (!IsSingleNumber)
>>> -                EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
>>> -            }
>>> -        }
>>> -        Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
>>> +        Vals.push_back(VE.getValueID(i.getCaseValue()));
>>> +        Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
>>>       }
>>> -
>>> -      Stream.EmitRecord(Code, Vals64, AbbrevToUse);
>>> -
>>> -      // Also do expected action - clear external Vals collection:
>>> -      Vals.clear();
>>> -      return;
>>>     }
>>>     break;
>>>   case Instruction::IndirectBr:
>>> 
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Sep  9 14:14:35 2013
>>> @@ -49,7 +49,6 @@
>>> #include "llvm/Support/CommandLine.h"
>>> #include "llvm/Support/Debug.h"
>>> #include "llvm/Support/ErrorHandling.h"
>>> -#include "llvm/Support/IntegersSubsetMapping.h"
>>> #include "llvm/Support/MathExtras.h"
>>> #include "llvm/Support/raw_ostream.h"
>>> #include "llvm/Target/TargetFrameLowering.h"
>>> @@ -1618,8 +1617,7 @@ void SelectionDAGBuilder::visitSwitchCas
>>>     } else
>>>       Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
>>>   } else {
>>> -    assert(CB.CC == ISD::SETCC_INVALID &&
>>> -           "Condition is undefined for to-the-range belonging check.");
>>> +    assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now");
>>> 
>>>     const APInt& Low = cast<ConstantInt>(CB.CmpLHS)->getValue();
>>>     const APInt& High  = cast<ConstantInt>(CB.CmpRHS)->getValue();
>>> @@ -1627,9 +1625,9 @@ void SelectionDAGBuilder::visitSwitchCas
>>>     SDValue CmpOp = getValue(CB.CmpMHS);
>>>     EVT VT = CmpOp.getValueType();
>>> 
>>> -    if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(false)) {
>>> +    if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
>>>       Cond = DAG.getSetCC(dl, MVT::i1, CmpOp, DAG.getConstant(High, VT),
>>> -                          ISD::SETULE);
>>> +                          ISD::SETLE);
>>>     } else {
>>>       SDValue SUB = DAG.getNode(ISD::SUB, dl,
>>>                                 VT, CmpOp, DAG.getConstant(Low, VT));
>>> @@ -2145,7 +2143,7 @@ bool SelectionDAGBuilder::handleSmallSwi
>>>       CC = ISD::SETEQ;
>>>       LHS = SV; RHS = I->High; MHS = NULL;
>>>     } else {
>>> -      CC = ISD::SETCC_INVALID;
>>> +      CC = ISD::SETLE;
>>>       LHS = I->Low; MHS = SV; RHS = I->High;
>>>     }
>>> 
>>> @@ -2179,7 +2177,7 @@ static inline bool areJTsAllowed(const T
>>> 
>>> static APInt ComputeRange(const APInt &First, const APInt &Last) {
>>>   uint32_t BitWidth = std::max(Last.getBitWidth(), First.getBitWidth()) + 1;
>>> -  APInt LastExt = Last.zext(BitWidth), FirstExt = First.zext(BitWidth);
>>> +  APInt LastExt = Last.sext(BitWidth), FirstExt = First.sext(BitWidth);
>>>   return (LastExt - FirstExt + 1ULL);
>>> }
>>> 
>>> @@ -2246,7 +2244,7 @@ bool SelectionDAGBuilder::handleJTSwitch
>>>     const APInt &Low = cast<ConstantInt>(I->Low)->getValue();
>>>     const APInt &High = cast<ConstantInt>(I->High)->getValue();
>>> 
>>> -    if (Low.ule(TEI) && TEI.ule(High)) {
>>> +    if (Low.sle(TEI) && TEI.sle(High)) {
>>>       DestBBs.push_back(I->BB);
>>>       if (TEI==High)
>>>         ++I;
>>> @@ -2420,7 +2418,7 @@ bool SelectionDAGBuilder::handleBTSplitS
>>>   // Create a CaseBlock record representing a conditional branch to
>>>   // the LHS node if the value being switched on SV is less than C.
>>>   // Otherwise, branch to LHS.
>>> -  CaseBlock CB(ISD::SETULT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB);
>>> +  CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB);
>>> 
>>>   if (CR.CaseBB == SwitchBB)
>>>     visitSwitchCase(CB, SwitchBB);
>>> @@ -2493,7 +2491,7 @@ bool SelectionDAGBuilder::handleBitTests
>>>   // Optimize the case where all the case values fit in a
>>>   // word without having to subtract minValue. In this case,
>>>   // we can optimize away the subtraction.
>>> -  if (maxValue.ult(IntPtrBits)) {
>>> +  if (minValue.isNonNegative() && maxValue.slt(IntPtrBits)) {
>>>     cmpRange = maxValue;
>>>   } else {
>>>     lowBound = minValue;
>>> @@ -2568,12 +2566,7 @@ bool SelectionDAGBuilder::handleBitTests
>>> /// Clusterify - Transform simple list of Cases into list of CaseRange's
>>> size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
>>>                                        const SwitchInst& SI) {
>>> -
>>> -  /// Use a shorter form of declaration, and also
>>> -  /// show the we want to use CRSBuilder as Clusterifier.
>>> -  typedef IntegersSubsetMapping<MachineBasicBlock> Clusterifier;
>>> -
>>> -  Clusterifier TheClusterifier;
>>> +  size_t numCmps = 0;
>>> 
>>>   BranchProbabilityInfo *BPI = FuncInfo.BPI;
>>>   // Start with "simple" cases
>>> @@ -2582,27 +2575,40 @@ size_t SelectionDAGBuilder::Clusterify(C
>>>     const BasicBlock *SuccBB = i.getCaseSuccessor();
>>>     MachineBasicBlock *SMBB = FuncInfo.MBBMap[SuccBB];
>>> 
>>> -    TheClusterifier.add(i.getCaseValueEx(), SMBB,
>>> -        BPI ? BPI->getEdgeWeight(SI.getParent(), i.getSuccessorIndex()) : 0);
>>> +    uint32_t ExtraWeight =
>>> +      BPI ? BPI->getEdgeWeight(SI.getParent(), i.getSuccessorIndex()) : 0;
>>> +
>>> +    Cases.push_back(Case(i.getCaseValue(), i.getCaseValue(),
>>> +                         SMBB, ExtraWeight));
>>>   }
>>> +  std::sort(Cases.begin(), Cases.end(), CaseCmp());
>>> 
>>> -  TheClusterifier.optimize();
>>> +  // Merge case into clusters
>>> +  if (Cases.size() >= 2)
>>> +    // Must recompute end() each iteration because it may be
>>> +    // invalidated by erase if we hold on to it
>>> +    for (CaseItr I = Cases.begin(), J = llvm::next(Cases.begin());
>>> +         J != Cases.end(); ) {
>>> +      const APInt& nextValue = cast<ConstantInt>(J->Low)->getValue();
>>> +      const APInt& currentValue = cast<ConstantInt>(I->High)->getValue();
>>> +      MachineBasicBlock* nextBB = J->BB;
>>> +      MachineBasicBlock* currentBB = I->BB;
>>> +
>>> +      // If the two neighboring cases go to the same destination, merge them
>>> +      // into a single case.
>>> +      if ((nextValue - currentValue == 1) && (currentBB == nextBB)) {
>>> +        I->High = J->High;
>>> +        I->ExtraWeight += J->ExtraWeight;
>>> +        J = Cases.erase(J);
>>> +      } else {
>>> +        I = J++;
>>> +      }
>>> +    }
>>> 
>>> -  size_t numCmps = 0;
>>> -  for (Clusterifier::RangeIterator i = TheClusterifier.begin(),
>>> -       e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
>>> -    Clusterifier::Cluster &C = *i;
>>> -    // Update edge weight for the cluster.
>>> -    unsigned W = C.first.Weight;
>>> -
>>> -    // FIXME: Currently work with ConstantInt based numbers.
>>> -    // Changing it to APInt based is a pretty heavy for this commit.
>>> -    Cases.push_back(Case(C.first.getLow().toConstantInt(),
>>> -                         C.first.getHigh().toConstantInt(), C.second, W));
>>> -
>>> -    if (C.first.getLow() != C.first.getHigh())
>>> -    // A range counts double, since it requires two compares.
>>> -    ++numCmps;
>>> +  for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) {
>>> +    if (I->Low != I->High)
>>> +      // A range counts double, since it requires two compares.
>>> +      ++numCmps;
>>>   }
>>> 
>>>   return numCmps;
>>> 
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Mon Sep  9 14:14:35 2013
>>> @@ -182,6 +182,17 @@ private:
>>> 
>>>   typedef std::vector<CaseRec> CaseRecVector;
>>> 
>>> +  /// The comparison function for sorting the switch case values in the vector.
>>> +  /// WARNING: Case ranges should be disjoint!
>>> +  struct CaseCmp {
>>> +    bool operator()(const Case &C1, const Case &C2) {
>>> +      assert(isa<ConstantInt>(C1.Low) && isa<ConstantInt>(C2.High));
>>> +      const ConstantInt* CI1 = cast<const ConstantInt>(C1.Low);
>>> +      const ConstantInt* CI2 = cast<const ConstantInt>(C2.High);
>>> +      return CI1->getValue().slt(CI2->getValue());
>>> +    }
>>> +  };
>>> +
>>>   struct CaseBitsCmp {
>>>     bool operator()(const CaseBits &C1, const CaseBits &C2) {
>>>       return C1.Bits > C2.Bits;
>>> 
>>> Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original)
>>> +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Mon Sep  9 14:14:35 2013
>>> @@ -898,40 +898,11 @@ void Interpreter::visitSwitchInst(Switch
>>>   // Check to see if any of the cases match...
>>>   BasicBlock *Dest = 0;
>>>   for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
>>> -    IntegersSubset& Case = i.getCaseValueEx();
>>> -    if (Case.isSingleNumber()) {
>>> -      // FIXME: Currently work with ConstantInt based numbers.
>>> -      const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt();
>>> -      GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
>>> -      if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
>>> -        Dest = cast<BasicBlock>(i.getCaseSuccessor());
>>> -        break;
>>> -      }
>>> +    GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF);
>>> +    if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
>>> +      Dest = cast<BasicBlock>(i.getCaseSuccessor());
>>> +      break;
>>>     }
>>> -    if (Case.isSingleNumbersOnly()) {
>>> -      for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
>>> -        // FIXME: Currently work with ConstantInt based numbers.
>>> -        const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt();
>>> -        GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
>>> -        if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
>>> -          Dest = cast<BasicBlock>(i.getCaseSuccessor());
>>> -          break;
>>> -        }
>>> -      }
>>> -    } else
>>> -      for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
>>> -        IntegersSubset::Range r = Case.getItem(n);
>>> -        // FIXME: Currently work with ConstantInt based numbers.
>>> -        const ConstantInt *LowCI = r.getLow().toConstantInt();
>>> -        const ConstantInt *HighCI = r.getHigh().toConstantInt();
>>> -        GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
>>> -        GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
>>> -        if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
>>> -            executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
>>> -          Dest = cast<BasicBlock>(i.getCaseSuccessor());
>>> -          break;
>>> -        }
>>> -      }
>>>   }
>>>   if (!Dest) Dest = I.getDefaultDest();   // No cases matched: use default
>>>   SwitchToNewBasicBlock(Dest, SF);
>>> 
>>> Modified: llvm/trunk/lib/IR/Instructions.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/IR/Instructions.cpp (original)
>>> +++ llvm/trunk/lib/IR/Instructions.cpp Mon Sep  9 14:14:35 2013
>>> @@ -3267,7 +3267,6 @@ SwitchInst::SwitchInst(const SwitchInst
>>>     OL[i] = InOL[i];
>>>     OL[i+1] = InOL[i+1];
>>>   }
>>> -  TheSubsets = SI.TheSubsets;
>>>   SubclassOptionalData = SI.SubclassOptionalData;
>>> }
>>> 
>>> @@ -3279,16 +3278,6 @@ SwitchInst::~SwitchInst() {
>>> /// addCase - Add an entry to the switch instruction...
>>> ///
>>> void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
>>> -  IntegersSubsetToBB Mapping;
>>> -
>>> -  // FIXME: Currently we work with ConstantInt based cases.
>>> -  // So inititalize IntItem container directly from ConstantInt.
>>> -  Mapping.add(IntItem::fromConstantInt(OnVal));
>>> -  IntegersSubset CaseRanges = Mapping.getCase();
>>> -  addCase(CaseRanges, Dest);
>>> -}
>>> -
>>> -void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) {
>>>   unsigned NewCaseIdx = getNumCases();
>>>   unsigned OpNo = NumOperands;
>>>   if (OpNo+2 > ReservedSpace)
>>> @@ -3296,17 +3285,14 @@ void SwitchInst::addCase(IntegersSubset&
>>>   // Initialize some new operands.
>>>   assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
>>>   NumOperands = OpNo+2;
>>> -
>>> -  SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal);
>>> -
>>> -  CaseIt Case(this, NewCaseIdx, TheSubsetsIt);
>>> -  Case.updateCaseValueOperand(OnVal);
>>> +  CaseIt Case(this, NewCaseIdx);
>>> +  Case.setValue(OnVal);
>>>   Case.setSuccessor(Dest);
>>> }
>>> 
>>> /// removeCase - This method removes the specified case and its successor
>>> /// from the switch instruction.
>>> -void SwitchInst::removeCase(CaseIt& i) {
>>> +void SwitchInst::removeCase(CaseIt i) {
>>>   unsigned idx = i.getCaseIndex();
>>> 
>>>   assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
>>> @@ -3323,16 +3309,6 @@ void SwitchInst::removeCase(CaseIt& i) {
>>>   // Nuke the last value.
>>>   OL[NumOps-2].set(0);
>>>   OL[NumOps-2+1].set(0);
>>> -
>>> -  // Do the same with TheCases collection:
>>> -  if (i.SubsetIt != --TheSubsets.end()) {
>>> -    *i.SubsetIt = TheSubsets.back();
>>> -    TheSubsets.pop_back();
>>> -  } else {
>>> -    TheSubsets.pop_back();
>>> -    i.SubsetIt = TheSubsets.end();
>>> -  }
>>> -
>>>   NumOperands = NumOps-2;
>>> }
>>> 
>>> 
>>> Modified: llvm/trunk/lib/IR/Verifier.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/IR/Verifier.cpp (original)
>>> +++ llvm/trunk/lib/IR/Verifier.cpp Mon Sep  9 14:14:35 2013
>>> @@ -1168,27 +1168,12 @@ void Verifier::visitSwitchInst(SwitchIns
>>>   // Check to make sure that all of the constants in the switch instruction
>>>   // have the same type as the switched-on value.
>>>   Type *SwitchTy = SI.getCondition()->getType();
>>> -  IntegerType *IntTy = cast<IntegerType>(SwitchTy);
>>> -  IntegersSubsetToBB Mapping;
>>> -  std::map<IntegersSubset::Range, unsigned> RangeSetMap;
>>> +  SmallPtrSet<ConstantInt*, 32> Constants;
>>>   for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
>>> -    IntegersSubset CaseRanges = i.getCaseValueEx();
>>> -    for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
>>> -      IntegersSubset::Range r = CaseRanges.getItem(ri);
>>> -      Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
>>> -              "Switch constants must all be same type as switch value!", &SI);
>>> -      Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
>>> -              "Switch constants must all be same type as switch value!", &SI);
>>> -      Mapping.add(r);
>>> -      RangeSetMap[r] = i.getCaseIndex();
>>> -    }
>>> -  }
>>> -
>>> -  IntegersSubsetToBB::RangeIterator errItem;
>>> -  if (!Mapping.verify(errItem)) {
>>> -    unsigned CaseIndex = RangeSetMap[errItem->first];
>>> -    SwitchInst::CaseIt i(&SI, CaseIndex);
>>> -    Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx());
>>> +    Assert1(i.getCaseValue()->getType() == SwitchTy,
>>> +            "Switch constants must all be same type as switch value!", &SI);
>>> +    Assert2(Constants.insert(i.getCaseValue()),
>>> +            "Duplicate integer as switch case", &SI, i.getCaseValue());
>>>   }
>>> 
>>>   visitTerminatorInst(SI);
>>> 
>>> Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
>>> +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Sep  9 14:14:35 2013
>>> @@ -1140,7 +1140,7 @@ void CppWriter::printInstruction(const I
>>>     nl(Out);
>>>     for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end();
>>>          i != e; ++i) {
>>> -      const IntegersSubset CaseVal = i.getCaseValueEx();
>>> +      const ConstantInt* CaseVal = i.getCaseValue();
>>>       const BasicBlock *BB = i.getCaseSuccessor();
>>>       Out << iName << "->addCase("
>>>           << getOpName(CaseVal) << ", "
>>> 
>>> Modified: llvm/trunk/lib/Transforms/Instrumentation/DebugIR.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/DebugIR.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Instrumentation/DebugIR.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Instrumentation/DebugIR.cpp Mon Sep  9 14:14:35 2013
>>> @@ -25,6 +25,7 @@
>>> #include "llvm/InstVisitor.h"
>>> #include "llvm/IR/DataLayout.h"
>>> #include "llvm/IR/Instruction.h"
>>> +#include "llvm/IR/LLVMContext.h"
>>> #include "llvm/IR/Module.h"
>>> #include "llvm/Transforms/Instrumentation.h"
>>> #include "llvm/Transforms/Utils/Cloning.h"
>>> 
>>> Modified: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Mon Sep  9 14:14:35 2013
>>> @@ -665,8 +665,7 @@ emitCallAndSwitchStatement(Function *new
>>>     TheSwitch->setCondition(call);
>>>     TheSwitch->setDefaultDest(TheSwitch->getSuccessor(NumExitBlocks));
>>>     // Remove redundant case
>>> -    SwitchInst::CaseIt ToBeRemoved(TheSwitch, NumExitBlocks-1);
>>> -    TheSwitch->removeCase(ToBeRemoved);
>>> +    TheSwitch->removeCase(SwitchInst::CaseIt(TheSwitch, NumExitBlocks-1));
>>>     break;
>>>   }
>>> }
>>> 
>>> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Sep  9 14:14:35 2013
>>> @@ -196,33 +196,28 @@ bool llvm::ConstantFoldTerminator(BasicB
>>>       // Otherwise, we can fold this switch into a conditional branch
>>>       // instruction if it has only one non-default destination.
>>>       SwitchInst::CaseIt FirstCase = SI->case_begin();
>>> -      IntegersSubset& Case = FirstCase.getCaseValueEx();
>>> -      if (Case.isSingleNumber()) {
>>> -        // FIXME: Currently work with ConstantInt based numbers.
>>> -        Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
>>> -             Case.getSingleNumber(0).toConstantInt(),
>>> -            "cond");
>>> +      Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
>>> +          FirstCase.getCaseValue(), "cond");
>>> 
>>> -        // Insert the new branch.
>>> -        BranchInst *NewBr = Builder.CreateCondBr(Cond,
>>> -                                FirstCase.getCaseSuccessor(),
>>> -                                SI->getDefaultDest());
>>> -        MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
>>> -        if (MD && MD->getNumOperands() == 3) {
>>> -          ConstantInt *SICase = dyn_cast<ConstantInt>(MD->getOperand(2));
>>> -          ConstantInt *SIDef = dyn_cast<ConstantInt>(MD->getOperand(1));
>>> -          assert(SICase && SIDef);
>>> -          // The TrueWeight should be the weight for the single case of SI.
>>> -          NewBr->setMetadata(LLVMContext::MD_prof,
>>> -                 MDBuilder(BB->getContext()).
>>> -                 createBranchWeights(SICase->getValue().getZExtValue(),
>>> -                                     SIDef->getValue().getZExtValue()));
>>> -        }
>>> -
>>> -        // Delete the old switch.
>>> -        SI->eraseFromParent();
>>> -        return true;
>>> +      // Insert the new branch.
>>> +      BranchInst *NewBr = Builder.CreateCondBr(Cond,
>>> +                                               FirstCase.getCaseSuccessor(),
>>> +                                               SI->getDefaultDest());
>>> +      MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
>>> +      if (MD && MD->getNumOperands() == 3) {
>>> +        ConstantInt *SICase = dyn_cast<ConstantInt>(MD->getOperand(2));
>>> +        ConstantInt *SIDef = dyn_cast<ConstantInt>(MD->getOperand(1));
>>> +        assert(SICase && SIDef);
>>> +        // The TrueWeight should be the weight for the single case of SI.
>>> +        NewBr->setMetadata(LLVMContext::MD_prof,
>>> +                        MDBuilder(BB->getContext()).
>>> +                        createBranchWeights(SICase->getValue().getZExtValue(),
>>> +                                            SIDef->getValue().getZExtValue()));
>>>       }
>>> +
>>> +      // Delete the old switch.
>>> +      SI->eraseFromParent();
>>> +      return true;
>>>     }
>>>     return false;
>>>   }
>>> 
>>> Modified: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp Mon Sep  9 14:14:35 2013
>>> @@ -66,6 +66,18 @@ namespace {
>>>                              BasicBlock* OrigBlock, BasicBlock* Default);
>>>     unsigned Clusterify(CaseVector& Cases, SwitchInst *SI);
>>>   };
>>> +
>>> +  /// The comparison function for sorting the switch case values in the vector.
>>> +  /// WARNING: Case ranges should be disjoint!
>>> +  struct CaseCmp {
>>> +    bool operator () (const LowerSwitch::CaseRange& C1,
>>> +                      const LowerSwitch::CaseRange& C2) {
>>> +
>>> +      const ConstantInt* CI1 = cast<const ConstantInt>(C1.Low);
>>> +      const ConstantInt* CI2 = cast<const ConstantInt>(C2.High);
>>> +      return CI1->getValue().slt(CI2->getValue());
>>> +    }
>>> +  };
>>> }
>>> 
>>> char LowerSwitch::ID = 0;
>>> @@ -147,7 +159,7 @@ BasicBlock* LowerSwitch::switchConvert(C
>>>   Function::iterator FI = OrigBlock;
>>>   F->getBasicBlockList().insert(++FI, NewNode);
>>> 
>>> -  ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_ULT,
>>> +  ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_SLT,
>>>                                 Val, Pivot.Low, "Pivot");
>>>   NewNode->getInstList().push_back(Comp);
>>>   BranchInst::Create(LBranch, RBranch, Comp, NewNode);
>>> @@ -222,34 +234,40 @@ BasicBlock* LowerSwitch::newLeafBlock(Ca
>>> 
>>> // Clusterify - Transform simple list of Cases into list of CaseRange's
>>> unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
>>> -
>>> -  IntegersSubsetToBB TheClusterifier;
>>> +  unsigned numCmps = 0;
>>> 
>>>   // Start with "simple" cases
>>> -  for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
>>> -       i != e; ++i) {
>>> -    BasicBlock *SuccBB = i.getCaseSuccessor();
>>> -    IntegersSubset CaseRanges = i.getCaseValueEx();
>>> -    TheClusterifier.add(CaseRanges, SuccBB);
>>> -  }
>>> +  for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i)
>>> +    Cases.push_back(CaseRange(i.getCaseValue(), i.getCaseValue(),
>>> +                              i.getCaseSuccessor()));
>>> 
>>> -  TheClusterifier.optimize();
>>> -
>>> -  size_t numCmps = 0;
>>> -  for (IntegersSubsetToBB::RangeIterator i = TheClusterifier.begin(),
>>> -       e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
>>> -    IntegersSubsetToBB::Cluster &C = *i;
>>> -
>>> -    // FIXME: Currently work with ConstantInt based numbers.
>>> -    // Changing it to APInt based is a pretty heavy for this commit.
>>> -    Cases.push_back(CaseRange(C.first.getLow().toConstantInt(),
>>> -                              C.first.getHigh().toConstantInt(), C.second));
>>> -    if (C.first.isSingleNumber())
>>> +  std::sort(Cases.begin(), Cases.end(), CaseCmp());
>>> +
>>> +  // Merge case into clusters
>>> +  if (Cases.size()>=2)
>>> +    for (CaseItr I=Cases.begin(), J=llvm::next(Cases.begin()); J!=Cases.end(); ) {
>>> +      int64_t nextValue = cast<ConstantInt>(J->Low)->getSExtValue();
>>> +      int64_t currentValue = cast<ConstantInt>(I->High)->getSExtValue();
>>> +      BasicBlock* nextBB = J->BB;
>>> +      BasicBlock* currentBB = I->BB;
>>> +
>>> +      // If the two neighboring cases go to the same destination, merge them
>>> +      // into a single case.
>>> +      if ((nextValue-currentValue==1) && (currentBB == nextBB)) {
>>> +        I->High = J->High;
>>> +        J = Cases.erase(J);
>>> +      } else {
>>> +        I = J++;
>>> +      }
>>> +    }
>>> +
>>> +  for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) {
>>> +    if (I->Low != I->High)
>>>       // A range counts double, since it requires two compares.
>>>       ++numCmps;
>>>   }
>>> 
>>> -  return numCmps;
>>> +  return numCmps;
>>> }
>>> 
>>> // processSwitchInst - Replace the specified switch instruction with a sequence
>>> 
>>> Removed: llvm/trunk/test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll?rev=190327&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll (original)
>>> +++ llvm/trunk/test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll (removed)
>>> @@ -1,33 +0,0 @@
>>> -; RUN: rm -f %t.bc
>>> -; RUN: rm -f %t.ll
>>> -; RUN: rm -f %t2.bc
>>> -; RUN: rm -f %t2.ll
>>> -; RUN: llvm-as %s -o %t.bc
>>> -; RUN: llvm-dis %t.bc -o - | tail -n +2 > %t.ll
>>> -; RUN: llvm-as %t.ll -o %t2.bc
>>> -; RUN: llvm-dis %t2.bc -o - | tail -n +2 > %t2.ll
>>> -; RUN: llvm-diff %t.ll %t2.ll
>>> -
>>> -define void @test() {
>>> -  %mem = alloca i32
>>> -  store i32 2, i32* %mem
>>> -  %c = load i32* %mem
>>> -  switch i32 %c, label %exit [
>>> -      i32 1, label %exit
>>> -      i32 2, label %exit
>>> -  ]
>>> -exit:
>>> -  ret void
>>> -}
>>> -define void @test_wide() {
>>> -  %mem = alloca i256
>>> -  store i256 2, i256* %mem
>>> -  %c = load i256* %mem
>>> -  switch i256 %c, label %exit [
>>> -      i256 123456789012345678901234567890, label %exit
>>> -      i256 2, label %exit
>>> -  ]
>>> -exit:
>>> -  ret void
>>> -}
>>> -
>>> 
>>> Added: llvm/trunk/test/Bitcode/case-ranges-3.3.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/case-ranges-3.3.ll?rev=190328&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/test/Bitcode/case-ranges-3.3.ll (added)
>>> +++ llvm/trunk/test/Bitcode/case-ranges-3.3.ll Mon Sep  9 14:14:35 2013
>>> @@ -0,0 +1,67 @@
>>> +; RUN:  llvm-dis < %s.bc| FileCheck %s
>>> +
>>> +; case-ranges.ll.bc was generated by passing this file to llvm-as from the 3.3
>>> +; release of LLVM. This tests that the bitcode for switches from that release
>>> +; can still be read.
>>> +
>>> +define i32 @foo(i32 %x) nounwind ssp uwtable {
>>> +; CHECK: define i32 @foo
>>> +  %1 = alloca i32, align 4
>>> +  %2 = alloca i32, align 4
>>> +  store i32 %x, i32* %2, align 4
>>> +  %3 = load i32* %2, align 4
>>> +  switch i32 %3, label %9 [
>>> +; CHECK: switch i32 %3, label %9
>>> +    i32 -3, label %4
>>> +; CHECK-NEXT: i32 -3, label %4
>>> +    i32 -2, label %4
>>> +; CHECK-NEXT: i32 -2, label %4
>>> +    i32 -1, label %4
>>> +; CHECK-NEXT: i32 -1, label %4
>>> +    i32 0, label %4
>>> +; CHECK-NEXT: i32 0, label %4
>>> +    i32 1, label %4
>>> +; CHECK-NEXT: i32 1, label %4
>>> +    i32 2, label %4
>>> +; CHECK-NEXT: i32 2, label %4
>>> +    i32 4, label %5
>>> +; CHECK-NEXT: i32 4, label %5
>>> +    i32 5, label %6
>>> +; CHECK-NEXT: i32 5, label %6
>>> +    i32 6, label %7
>>> +; CHECK-NEXT: i32 6, label %7
>>> +    i32 7, label %8
>>> +; CHECK-NEXT: i32 7, label %8
>>> +  ]
>>> +
>>> +; <label>:4
>>> +  store i32 -1, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:5
>>> +  store i32 2, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:6
>>> +  store i32 1, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:7
>>> +  store i32 4, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:8
>>> +  store i32 3, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:9
>>> +  br label %10
>>> +
>>> +; <label>:10
>>> +  store i32 0, i32* %1
>>> +  br label %11
>>> +
>>> +; <label>:11
>>> +  %12 = load i32* %1
>>> +  ret i32 %12
>>> +}
>>> 
>>> Added: llvm/trunk/test/Bitcode/case-ranges-3.3.ll.bc
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/case-ranges-3.3.ll.bc?rev=190328&view=auto
>>> ==============================================================================
>>> Binary files llvm/trunk/test/Bitcode/case-ranges-3.3.ll.bc (added) and llvm/trunk/test/Bitcode/case-ranges-3.3.ll.bc Mon Sep  9 14:14:35 2013 differ
>>> 
>>> Modified: llvm/trunk/test/Transforms/LowerSwitch/feature.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerSwitch/feature.ll?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/LowerSwitch/feature.ll (original)
>>> +++ llvm/trunk/test/Transforms/LowerSwitch/feature.ll Mon Sep  9 14:14:35 2013
>>> @@ -7,88 +7,88 @@
>>> ;CHECK-NEXT:   br label %NodeBlock37
>>> 
>>> ;CHECK:      NodeBlock37:                                      ; preds = %entry
>>> -;CHECK-NEXT:   %Pivot38 = icmp ult i32 %tmp158, 11
>>> +;CHECK-NEXT:   %Pivot38 = icmp slt i32 %tmp158, 10
>>> ;CHECK-NEXT:   br i1 %Pivot38, label %NodeBlock13, label %NodeBlock35
>>> 
>>> ;CHECK:      NodeBlock35:                                      ; preds = %NodeBlock37
>>> -;CHECK-NEXT:   %Pivot36 = icmp ult i32 %tmp158, 14
>>> +;CHECK-NEXT:   %Pivot36 = icmp slt i32 %tmp158, 13
>>> ;CHECK-NEXT:   br i1 %Pivot36, label %NodeBlock23, label %NodeBlock33
>>> 
>>> ;CHECK:      NodeBlock33:                                      ; preds = %NodeBlock35
>>> -;CHECK-NEXT:   %Pivot34 = icmp ult i32 %tmp158, 15
>>> +;CHECK-NEXT:   %Pivot34 = icmp slt i32 %tmp158, 14
>>> ;CHECK-NEXT:   br i1 %Pivot34, label %LeafBlock25, label %NodeBlock31
>>> 
>>> ;CHECK:      NodeBlock31:                                      ; preds = %NodeBlock33
>>> -;CHECK-NEXT:   %Pivot32 = icmp ult i32 %tmp158, -6
>>> +;CHECK-NEXT:   %Pivot32 = icmp slt i32 %tmp158, 15
>>> ;CHECK-NEXT:   br i1 %Pivot32, label %LeafBlock27, label %LeafBlock29
>>> 
>>> ;CHECK:      LeafBlock29:                                      ; preds = %NodeBlock31
>>> -;CHECK-NEXT:   %tmp158.off = add i32 %tmp158, 6
>>> -;CHECK-NEXT:   %SwitchLeaf30 = icmp ule i32 %tmp158.off, 4
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf30, label %bb338, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf30 = icmp eq i32 %tmp158, 15
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf30, label %bb334, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock27:                                      ; preds = %NodeBlock31
>>> -;CHECK-NEXT:   %SwitchLeaf28 = icmp eq i32 %tmp158, 15
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf28, label %bb334, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf28 = icmp eq i32 %tmp158, 14
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf28, label %bb332, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock25:                                      ; preds = %NodeBlock33
>>> -;CHECK-NEXT:   %SwitchLeaf26 = icmp eq i32 %tmp158, 14
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf26, label %bb332, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf26 = icmp eq i32 %tmp158, 13
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf26, label %bb330, label %NewDefault
>>> 
>>> ;CHECK:      NodeBlock23:                                      ; preds = %NodeBlock35
>>> -;CHECK-NEXT:   %Pivot24 = icmp ult i32 %tmp158, 12
>>> +;CHECK-NEXT:   %Pivot24 = icmp slt i32 %tmp158, 11
>>> ;CHECK-NEXT:   br i1 %Pivot24, label %LeafBlock15, label %NodeBlock21
>>> 
>>> ;CHECK:      NodeBlock21:                                      ; preds = %NodeBlock23
>>> -;CHECK-NEXT:   %Pivot22 = icmp ult i32 %tmp158, 13
>>> +;CHECK-NEXT:   %Pivot22 = icmp slt i32 %tmp158, 12
>>> ;CHECK-NEXT:   br i1 %Pivot22, label %LeafBlock17, label %LeafBlock19
>>> 
>>> ;CHECK:      LeafBlock19:                                      ; preds = %NodeBlock21
>>> -;CHECK-NEXT:   %SwitchLeaf20 = icmp eq i32 %tmp158, 13
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf20, label %bb330, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf20 = icmp eq i32 %tmp158, 12
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf20, label %bb328, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock17:                                      ; preds = %NodeBlock21
>>> -;CHECK-NEXT:   %SwitchLeaf18 = icmp eq i32 %tmp158, 12
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf18, label %bb328, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf18 = icmp eq i32 %tmp158, 11
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf18, label %bb326, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock15:                                      ; preds = %NodeBlock23
>>> -;CHECK-NEXT:   %SwitchLeaf16 = icmp eq i32 %tmp158, 11
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf16, label %bb326, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf16 = icmp eq i32 %tmp158, 10
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf16, label %bb324, label %NewDefault
>>> 
>>> ;CHECK:      NodeBlock13:                                      ; preds = %NodeBlock37
>>> -;CHECK-NEXT:   %Pivot14 = icmp ult i32 %tmp158, 8
>>> +;CHECK-NEXT:   %Pivot14 = icmp slt i32 %tmp158, 7
>>> ;CHECK-NEXT:   br i1 %Pivot14, label %NodeBlock, label %NodeBlock11
>>> 
>>> ;CHECK:      NodeBlock11:                                      ; preds = %NodeBlock13
>>> -;CHECK-NEXT:   %Pivot12 = icmp ult i32 %tmp158, 9
>>> +;CHECK-NEXT:   %Pivot12 = icmp slt i32 %tmp158, 8
>>> ;CHECK-NEXT:   br i1 %Pivot12, label %LeafBlock3, label %NodeBlock9
>>> 
>>> ;CHECK:      NodeBlock9:                                       ; preds = %NodeBlock11
>>> -;CHECK-NEXT:   %Pivot10 = icmp ult i32 %tmp158, 10
>>> +;CHECK-NEXT:   %Pivot10 = icmp slt i32 %tmp158, 9
>>> ;CHECK-NEXT:   br i1 %Pivot10, label %LeafBlock5, label %LeafBlock7
>>> 
>>> ;CHECK:      LeafBlock7:                                       ; preds = %NodeBlock9
>>> -;CHECK-NEXT:   %SwitchLeaf8 = icmp eq i32 %tmp158, 10
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf8, label %bb324, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf8 = icmp eq i32 %tmp158, 9
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf8, label %bb322, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock5:                                       ; preds = %NodeBlock9
>>> -;CHECK-NEXT:   %SwitchLeaf6 = icmp eq i32 %tmp158, 9
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf6, label %bb322, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf6 = icmp eq i32 %tmp158, 8
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf6, label %bb338, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock3:                                       ; preds = %NodeBlock11
>>> -;CHECK-NEXT:   %SwitchLeaf4 = icmp eq i32 %tmp158, 8
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf4, label %bb338, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf4 = icmp eq i32 %tmp158, 7
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf4, label %bb, label %NewDefault
>>> 
>>> ;CHECK:      NodeBlock:                                        ; preds = %NodeBlock13
>>> -;CHECK-NEXT:   %Pivot = icmp ult i32 %tmp158, 7
>>> +;CHECK-NEXT:   %Pivot = icmp slt i32 %tmp158, 0
>>> ;CHECK-NEXT:   br i1 %Pivot, label %LeafBlock, label %LeafBlock1
>>> 
>>> ;CHECK:      LeafBlock1:                                       ; preds = %NodeBlock
>>> -;CHECK-NEXT:   %SwitchLeaf2 = icmp eq i32 %tmp158, 7
>>> -;CHECK-NEXT:   br i1 %SwitchLeaf2, label %bb, label %NewDefault
>>> +;CHECK-NEXT:   %SwitchLeaf2 = icmp ule i32 %tmp158, 6
>>> +;CHECK-NEXT:   br i1 %SwitchLeaf2, label %bb338, label %NewDefault
>>> 
>>> ;CHECK:      LeafBlock:                                        ; preds = %NodeBlock
>>> -;CHECK-NEXT:   %SwitchLeaf = icmp ule i32 %tmp158, 6
>>> +;CHECK-NEXT:   %tmp158.off = add i32 %tmp158, 6
>>> +;CHECK-NEXT:   %SwitchLeaf = icmp ule i32 %tmp158.off, 4
>>> ;CHECK-NEXT:   br i1 %SwitchLeaf, label %bb338, label %NewDefault
>>> 
>>> define i32 @main(i32 %tmp158) {
>>> 
>>> Modified: llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp (original)
>>> +++ llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp Mon Sep  9 14:14:35 2013
>>> @@ -316,15 +316,15 @@ class FunctionDifferenceEngine {
>>> 
>>>       bool Difference = false;
>>> 
>>> -      DenseMap<Constant*, BasicBlock*> LCases;
>>> +      DenseMap<ConstantInt*,BasicBlock*> LCases;
>>> 
>>>       for (SwitchInst::CaseIt I = LI->case_begin(), E = LI->case_end();
>>>            I != E; ++I)
>>> -        LCases[I.getCaseValueEx()] = I.getCaseSuccessor();
>>> +        LCases[I.getCaseValue()] = I.getCaseSuccessor();
>>> 
>>>       for (SwitchInst::CaseIt I = RI->case_begin(), E = RI->case_end();
>>>            I != E; ++I) {
>>> -        IntegersSubset CaseValue = I.getCaseValueEx();
>>> +        ConstantInt *CaseValue = I.getCaseValue();
>>>         BasicBlock *LCase = LCases[CaseValue];
>>>         if (LCase) {
>>>           if (TryUnify) tryUnify(LCase, I.getCaseSuccessor());
>>> @@ -336,7 +336,7 @@ class FunctionDifferenceEngine {
>>>         }
>>>       }
>>>       if (!Difference)
>>> -        for (DenseMap<Constant*, BasicBlock*>::iterator
>>> +        for (DenseMap<ConstantInt*,BasicBlock*>::iterator
>>>                I = LCases.begin(), E = LCases.end(); I != E; ++I) {
>>>           if (Complain)
>>>             Engine.logf("left switch has extra case %l") << I->first;
>>> 
>>> Modified: llvm/trunk/unittests/IR/WaymarkTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/WaymarkTest.cpp?rev=190328&r1=190327&r2=190328&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/unittests/IR/WaymarkTest.cpp (original)
>>> +++ llvm/trunk/unittests/IR/WaymarkTest.cpp Mon Sep  9 14:14:35 2013
>>> @@ -9,6 +9,7 @@
>>> 
>>> // we perform white-box tests
>>> //
>>> +#include "llvm/IR/Constants.h"
>>> #include "llvm/IR/Function.h"
>>> #include "llvm/IR/Instructions.h"
>>> #include "llvm/IR/LLVMContext.h"
>>> 
>>> Removed: llvm/trunk/unittests/Support/IntegersSubsetTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/IntegersSubsetTest.cpp?rev=190327&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/IntegersSubsetTest.cpp (original)
>>> +++ llvm/trunk/unittests/Support/IntegersSubsetTest.cpp (removed)
>>> @@ -1,326 +0,0 @@
>>> -//===- llvm/unittest/Support/IntegersSubsetTest.cpp - IntegersSubset tests ===//
>>> -//
>>> -//                     The LLVM Compiler Infrastructure
>>> -//
>>> -// This file is distributed under the University of Illinois Open Source
>>> -// License. See LICENSE.TXT for details.
>>> -//
>>> -//===----------------------------------------------------------------------===//
>>> -
>>> -#include "llvm/Support/IntegersSubset.h"
>>> -#include "llvm/ADT/APInt.h"
>>> -#include "llvm/Support/IntegersSubsetMapping.h"
>>> -#include "gtest/gtest.h"
>>> -#include <vector>
>>> -
>>> -using namespace llvm;
>>> -
>>> -namespace {
>>> -
>>> -  class Int : public APInt {
>>> -  public:
>>> -    Int() {}
>>> -    Int(uint64_t V) : APInt(64, V) {}
>>> -    Int(const APInt& Src) : APInt(Src) {}
>>> -    bool operator < (const APInt& RHS) const { return ult(RHS); }
>>> -    bool operator > (const APInt& RHS) const { return ugt(RHS); }
>>> -    bool operator <= (const APInt& RHS) const { return ule(RHS); }
>>> -    bool operator >= (const APInt& RHS) const { return uge(RHS); }
>>> -  };
>>> -
>>> -  typedef IntRange<Int> Range;
>>> -  typedef IntegersSubsetGeneric<Int> Subset;
>>> -  typedef IntegersSubsetMapping<unsigned,Subset,Int> Mapping;
>>> -
>>> -  TEST(IntegersSubsetTest, GeneralTest) {
>>> -
>>> -    // Test construction.
>>> -
>>> -    std::vector<Range> Ranges;
>>> -    Ranges.reserve(3);
>>> -
>>> -    // Initialize Subset as union of three pairs:
>>> -    // { {0, 8}, {10, 18}, {20, 28} }
>>> -    for (unsigned i = 0; i < 3; ++i)
>>> -      Ranges.push_back(Range(Int(i*10), Int(i*10 + 8)));
>>> -
>>> -    Subset TheSubset(Ranges);
>>> -
>>> -    for (unsigned i = 0; i < 3; ++i) {
>>> -      EXPECT_EQ(TheSubset.getItem(i).getLow(), Int(i*10));
>>> -      EXPECT_EQ(TheSubset.getItem(i).getHigh(), Int(i*10 + 8));
>>> -    }
>>> -
>>> -    EXPECT_EQ(TheSubset.getNumItems(), 3ULL);
>>> -
>>> -    // Test belonging to range.
>>> -
>>> -    EXPECT_TRUE(TheSubset.isSatisfies(Int(5)));
>>> -    EXPECT_FALSE(TheSubset.isSatisfies(Int(9)));
>>> -
>>> -    // Test when subset contains the only item.
>>> -
>>> -    Ranges.clear();
>>> -    Ranges.push_back(Range(Int(10), Int(10)));
>>> -
>>> -    Subset TheSingleNumber(Ranges);
>>> -
>>> -    EXPECT_TRUE(TheSingleNumber.isSingleNumber());
>>> -
>>> -    Ranges.push_back(Range(Int(12), Int(15)));
>>> -
>>> -    Subset NotASingleNumber(Ranges);
>>> -
>>> -    EXPECT_FALSE(NotASingleNumber.isSingleNumber());
>>> -
>>> -    // Test when subset contains items that are not a ranges but
>>> -    // the single numbers.
>>> -
>>> -    Ranges.clear();
>>> -    Ranges.push_back(Range(Int(10), Int(10)));
>>> -    Ranges.push_back(Range(Int(15), Int(19)));
>>> -
>>> -    Subset WithSingleNumberItems(Ranges);
>>> -
>>> -    EXPECT_TRUE(WithSingleNumberItems.isSingleNumber(0));
>>> -    EXPECT_FALSE(WithSingleNumberItems.isSingleNumber(1));
>>> -
>>> -    // Test size of subset. Note subset itself may be not optimized (improper),
>>> -    // so it may contain duplicates, and the size of subset { {0, 9} {5, 9} }
>>> -    // will 15 instead of 10.
>>> -
>>> -    Ranges.clear();
>>> -    Ranges.push_back(Range(Int(0), Int(9)));
>>> -    Ranges.push_back(Range(Int(5), Int(9)));
>>> -
>>> -    Subset NotOptimizedSubset(Ranges);
>>> -
>>> -    EXPECT_EQ(NotOptimizedSubset.getSize(), 15ULL);
>>> -
>>> -    // Test access to a single value.
>>> -    // getSingleValue(idx) method represents subset as flat numbers collection,
>>> -    // so subset { {0, 3}, {8, 10} } will represented as array
>>> -    // { 0, 1, 2, 3, 8, 9, 10 }.
>>> -
>>> -    Ranges.clear();
>>> -    Ranges.push_back(Range(Int(0), Int(3)));
>>> -    Ranges.push_back(Range(Int(8), Int(10)));
>>> -
>>> -    Subset OneMoreSubset(Ranges);
>>> -
>>> -    EXPECT_EQ(OneMoreSubset.getSingleValue(5), Int(9));
>>> -  }
>>> -
>>> -  TEST(IntegersSubsetTest, MappingTest) {
>>> -
>>> -    Mapping::Cases TheCases;
>>> -
>>> -    unsigned Successors[3] = {0, 1, 2};
>>> -
>>> -    // Test construction.
>>> -
>>> -    Mapping TheMapping;
>>> -    for (unsigned i = 0; i < 3; ++i)
>>> -      TheMapping.add(Int(10*i), Int(10*i + 9), Successors + i);
>>> -    TheMapping.add(Int(111), Int(222), Successors);
>>> -    TheMapping.removeItem(--TheMapping.end());
>>> -
>>> -    TheMapping.getCases(TheCases);
>>> -
>>> -    EXPECT_EQ(TheCases.size(), 3ULL);
>>> -
>>> -    for (unsigned i = 0; i < 3; ++i) {
>>> -      Mapping::Cases::iterator CaseIt = TheCases.begin();
>>> -      std::advance(CaseIt, i);
>>> -      EXPECT_EQ(CaseIt->first, Successors + i);
>>> -      EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL);
>>> -      EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(10*i), Int(10*i + 9)));
>>> -    }
>>> -
>>> -    // Test verification.
>>> -
>>> -    Mapping ImproperMapping;
>>> -    ImproperMapping.add(Int(10), Int(11), Successors + 0);
>>> -    ImproperMapping.add(Int(11), Int(12), Successors + 1);
>>> -
>>> -    Mapping::RangeIterator ErrItem;
>>> -    EXPECT_FALSE(ImproperMapping.verify(ErrItem));
>>> -    EXPECT_EQ(ErrItem, --ImproperMapping.end());
>>> -
>>> -    Mapping ProperMapping;
>>> -    ProperMapping.add(Int(10), Int(11), Successors + 0);
>>> -    ProperMapping.add(Int(12), Int(13), Successors + 1);
>>> -
>>> -    EXPECT_TRUE(ProperMapping.verify(ErrItem));
>>> -
>>> -    // Test optimization.
>>> -
>>> -    Mapping ToBeOptimized;
>>> -
>>> -    for (unsigned i = 0; i < 3; ++i) {
>>> -      ToBeOptimized.add(Int(i * 10), Int(i * 10 + 1), Successors + i);
>>> -      ToBeOptimized.add(Int(i * 10 + 2), Int(i * 10 + 9), Successors + i);
>>> -    }
>>> -
>>> -    ToBeOptimized.optimize();
>>> -
>>> -    TheCases.clear();
>>> -    ToBeOptimized.getCases(TheCases);
>>> -
>>> -    EXPECT_EQ(TheCases.size(), 3ULL);
>>> -
>>> -    for (unsigned i = 0; i < 3; ++i) {
>>> -      Mapping::Cases::iterator CaseIt = TheCases.begin();
>>> -      std::advance(CaseIt, i);
>>> -      EXPECT_EQ(CaseIt->first, Successors + i);
>>> -      EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL);
>>> -      EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(i * 10), Int(i * 10 + 9)));
>>> -    }
>>> -  }
>>> -
>>> -  typedef unsigned unsigned_pair[2];
>>> -  typedef unsigned_pair unsigned_ranges[];
>>> -
>>> -  void TestDiff(
>>> -      const unsigned_ranges LHS,
>>> -      unsigned LSize,
>>> -      const unsigned_ranges RHS,
>>> -      unsigned RSize,
>>> -      const unsigned_ranges ExcludeRes,
>>> -      unsigned ExcludeResSize,
>>> -      const unsigned_ranges IntersectRes,
>>> -      unsigned IntersectResSize
>>> -      ) {
>>> -
>>> -    Mapping::RangesCollection Ranges;
>>> -
>>> -    Mapping LHSMapping;
>>> -    for (unsigned i = 0; i < LSize; ++i)
>>> -      Ranges.push_back(Range(Int(LHS[i][0]), Int(LHS[i][1])));
>>> -    LHSMapping.add(Ranges);
>>> -
>>> -    Ranges.clear();
>>> -
>>> -    Mapping RHSMapping;
>>> -    for (unsigned i = 0; i < RSize; ++i)
>>> -      Ranges.push_back(Range(Int(RHS[i][0]), Int(RHS[i][1])));
>>> -    RHSMapping.add(Ranges);
>>> -
>>> -    Mapping LExclude, Intersection;
>>> -
>>> -    LHSMapping.diff(&LExclude, &Intersection, 0, RHSMapping);
>>> -
>>> -    if (ExcludeResSize) {
>>> -      EXPECT_EQ(LExclude.size(), ExcludeResSize);
>>> -
>>> -      unsigned i = 0;
>>> -      for (Mapping::RangeIterator rei = LExclude.begin(),
>>> -           e = LExclude.end(); rei != e; ++rei, ++i)
>>> -        EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
>>> -    } else
>>> -      EXPECT_TRUE(LExclude.empty());
>>> -
>>> -    if (IntersectResSize) {
>>> -      EXPECT_EQ(Intersection.size(), IntersectResSize);
>>> -
>>> -      unsigned i = 0;
>>> -      for (Mapping::RangeIterator ii = Intersection.begin(),
>>> -           e = Intersection.end(); ii != e; ++ii, ++i)
>>> -        EXPECT_EQ(ii->first, Range(IntersectRes[i][0], IntersectRes[i][1]));
>>> -    } else
>>> -      EXPECT_TRUE(Intersection.empty());
>>> -
>>> -    LExclude.clear();
>>> -    Intersection.clear();
>>> -    RHSMapping.diff(0, &Intersection, &LExclude, LHSMapping);
>>> -
>>> -    // Check LExclude again.
>>> -    if (ExcludeResSize) {
>>> -      EXPECT_EQ(LExclude.size(), ExcludeResSize);
>>> -
>>> -      unsigned i = 0;
>>> -      for (Mapping::RangeIterator rei = LExclude.begin(),
>>> -           e = LExclude.end(); rei != e; ++rei, ++i)
>>> -        EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
>>> -    } else
>>> -      EXPECT_TRUE(LExclude.empty());
>>> -  }
>>> -
>>> -  TEST(IntegersSubsetTest, DiffTest) {
>>> -
>>> -    static const unsigned NOT_A_NUMBER = 0xffff;
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } };
>>> -      unsigned_ranges RHS = { { 3, 14 } };
>>> -      unsigned_ranges ExcludeRes = { { 0, 2 }, { 15, 17 } };
>>> -      unsigned_ranges IntersectRes = { { 3, 4 }, { 7, 10 }, { 13, 14 } };
>>> -
>>> -      TestDiff(LHS, 3, RHS, 1, ExcludeRes, 2, IntersectRes, 3);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } };
>>> -      unsigned_ranges RHS = { { 0, 4 }, { 13, 17 } };
>>> -      unsigned_ranges ExcludeRes = { { 7, 10 } };
>>> -      unsigned_ranges IntersectRes = { { 0, 4 }, { 13, 17 } };
>>> -
>>> -      TestDiff(LHS, 3, RHS, 2, ExcludeRes, 1, IntersectRes, 2);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 0, 17 } };
>>> -      unsigned_ranges RHS = { { 1, 5 }, { 10, 12 }, { 15, 16 } };
>>> -      unsigned_ranges ExcludeRes =
>>> -          { { 0, 0 }, { 6, 9 }, { 13, 14 }, { 17, 17 } };
>>> -      unsigned_ranges IntersectRes = { { 1, 5 }, { 10, 12 }, { 15, 16 } };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 3, ExcludeRes, 4, IntersectRes, 3);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 2, 4 } };
>>> -      unsigned_ranges RHS = { { 0, 5 } };
>>> -      unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
>>> -      unsigned_ranges IntersectRes = { { 2, 4 } };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 1, ExcludeRes, 0, IntersectRes, 1);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 2, 4 } };
>>> -      unsigned_ranges RHS = { { 7, 8 } };
>>> -      unsigned_ranges ExcludeRes = { { 2, 4 } };
>>> -      unsigned_ranges IntersectRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 3, 7 } };
>>> -      unsigned_ranges RHS = { { 1, 4 } };
>>> -      unsigned_ranges ExcludeRes = { { 5, 7 } };
>>> -      unsigned_ranges IntersectRes = { { 3, 4 } };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 1);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 0, 7 } };
>>> -      unsigned_ranges RHS = { { 0, 5 }, { 6, 9 } };
>>> -      unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
>>> -      unsigned_ranges IntersectRes = { { 0, 5 }, {6, 7} };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 2, ExcludeRes, 0, IntersectRes, 2);
>>> -    }
>>> -
>>> -    {
>>> -      unsigned_ranges LHS = { { 17, 17 } };
>>> -      unsigned_ranges RHS = { { 4, 4 } };
>>> -      unsigned_ranges ExcludeRes = { {17, 17} };
>>> -      unsigned_ranges IntersectRes = { { NOT_A_NUMBER, NOT_A_NUMBER } };
>>> -
>>> -      TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0);
>>> -    }
>>> -  }
>>> -}
>>> 
>> 
>> 
> 
> 




More information about the llvm-commits mailing list