llvm.org GIT mirror llvm / db3a9e6
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190328 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Wilson 6 years ago
22 changed file(s) with 414 addition(s) and 2051 deletion(s). Raw diff Collapse all Expand all
2222 #include "llvm/IR/DerivedTypes.h"
2323 #include "llvm/IR/InstrTypes.h"
2424 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/IntegersSubset.h"
26 #include "llvm/Support/IntegersSubsetMapping.h"
2725 #include
2826
2927 namespace llvm {
24562454 class SwitchInst : public TerminatorInst {
24572455 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
24582456 unsigned ReservedSpace;
2459 // Operands format:
24602457 // Operand[0] = Value to switch on
24612458 // Operand[1] = Default basic block destination
24622459 // Operand[2n ] = Value to match
24632460 // Operand[2n+1] = BasicBlock to go to on match
2464
2465 // Store case values separately from operands list. We needn't User-Use
2466 // concept here, since it is just a case value, it will always constant,
2467 // and case value couldn't reused with another instructions/values.
2468 // Additionally:
2469 // It allows us to use custom type for case values that is not inherited
2470 // from Value. Since case value is a complex type that implements
2471 // the subset of integers, we needn't extract sub-constants within
2472 // slow getAggregateElement method.
2473 // For case values we will use std::list to by two reasons:
2474 // 1. It allows to add/remove cases without whole collection reallocation.
2475 // 2. In most of cases we needn't random access.
2476 // Currently case values are also stored in Operands List, but it will moved
2477 // out in future commits.
2478 typedef std::list Subsets;
2479 typedef Subsets::iterator SubsetsIt;
2480 typedef Subsets::const_iterator SubsetsConstIt;
2481
2482 Subsets TheSubsets;
2483
24842461 SwitchInst(const SwitchInst &SI);
24852462 void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
24862463 void growOperands();
25052482 virtual SwitchInst *clone_impl() const;
25062483 public:
25072484
2508 // FIXME: Currently there are a lot of unclean template parameters,
2509 // we need to make refactoring in future.
2510 // All these parameters are used to implement both iterator and const_iterator
2511 // without code duplication.
2512 // SwitchInstTy may be "const SwitchInst" or "SwitchInst"
2513 // ConstantIntTy may be "const ConstantInt" or "ConstantInt"
2514 // SubsetsItTy may be SubsetsConstIt or SubsetsIt
2515 // BasicBlockTy may be "const BasicBlock" or "BasicBlock"
2516 template
2517 class SubsetsItTy, class BasicBlockTy>
2518 class CaseIteratorT;
2519
2520 typedef CaseIteratorT
2521 SubsetsConstIt, const BasicBlock> ConstCaseIt;
2522 class CaseIt;
2523
25242485 // -2
25252486 static const unsigned DefaultPseudoIndex = static_cast(~0L-1);
25262487
2527 static SwitchInst *Create(Value *Value, BasicBlock *Default,
2528 unsigned NumCases, Instruction *InsertBefore = 0) {
2529 return new SwitchInst(Value, Default, NumCases, InsertBefore);
2530 }
2531 static SwitchInst *Create(Value *Value, BasicBlock *Default,
2532 unsigned NumCases, BasicBlock *InsertAtEnd) {
2533 return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
2534 }
2535
2536 ~SwitchInst();
2537
2538 /// Provide fast operand accessors
2539 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2540
2541 // Accessor Methods for Switch stmt
2542 Value *getCondition() const { return getOperand(0); }
2543 void setCondition(Value *V) { setOperand(0, V); }
2544
2545 BasicBlock *getDefaultDest() const {
2546 return cast(getOperand(1));
2547 }
2548
2549 void setDefaultDest(BasicBlock *DefaultCase) {
2550 setOperand(1, reinterpret_cast(DefaultCase));
2551 }
2552
2553 /// getNumCases - return the number of 'cases' in this switch instruction,
2554 /// except the default case
2555 unsigned getNumCases() const {
2556 return getNumOperands()/2 - 1;
2557 }
2558
2559 /// Returns a read/write iterator that points to the first
2560 /// case in SwitchInst.
2561 CaseIt case_begin() {
2562 return CaseIt(this, 0, TheSubsets.begin());
2563 }
2564 /// Returns a read-only iterator that points to the first
2565 /// case in the SwitchInst.
2566 ConstCaseIt case_begin() const {
2567 return ConstCaseIt(this, 0, TheSubsets.begin());
2568 }
2569
2570 /// Returns a read/write iterator that points one past the last
2571 /// in the SwitchInst.
2572 CaseIt case_end() {
2573 return CaseIt(this, getNumCases(), TheSubsets.end());
2574 }
2575 /// Returns a read-only iterator that points one past the last
2576 /// in the SwitchInst.
2577 ConstCaseIt case_end() const {
2578 return ConstCaseIt(this, getNumCases(), TheSubsets.end());
2579 }
2580 /// Returns an iterator that points to the default case.
2581 /// Note: this iterator allows to resolve successor only. Attempt
2582 /// to resolve case value causes an assertion.
2583 /// Also note, that increment and decrement also causes an assertion and
2584 /// makes iterator invalid.
2585 CaseIt case_default() {
2586 return CaseIt(this, DefaultPseudoIndex, TheSubsets.end());
2587 }
2588 ConstCaseIt case_default() const {
2589 return ConstCaseIt(this, DefaultPseudoIndex, TheSubsets.end());
2590 }
2591
2592 /// findCaseValue - Search all of the case values for the specified constant.
2593 /// If it is explicitly handled, return the case iterator of it, otherwise
2594 /// return default case iterator to indicate
2595 /// that it is handled by the default handler.
2596 CaseIt findCaseValue(const ConstantInt *C) {
2597 for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
2598 if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
2599 return i;
2600 return case_default();
2601 }
2602 ConstCaseIt findCaseValue(const ConstantInt *C) const {
2603 for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
2604 if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
2605 return i;
2606 return case_default();
2607 }
2608
2609 /// findCaseDest - Finds the unique case value for a given successor. Returns
2610 /// null if the successor is not found, not unique, or is the default case.
2611 ConstantInt *findCaseDest(BasicBlock *BB) {
2612 if (BB == getDefaultDest()) return NULL;
2613
2614 ConstantInt *CI = NULL;
2615 for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
2616 if (i.getCaseSuccessor() == BB) {
2617 if (CI) return NULL; // Multiple cases lead to BB.
2618 else CI = i.getCaseValue();
2619 }
2620 }
2621 return CI;
2622 }
2623
2624 /// addCase - Add an entry to the switch instruction...
2625 /// Note:
2626 /// This action invalidates case_end(). Old case_end() iterator will
2627 /// point to the added case.
2628 void addCase(ConstantInt *OnVal, BasicBlock *Dest);
2629
2630 /// addCase - Add an entry to the switch instruction.
2631 /// Note:
2632 /// This action invalidates case_end(). Old case_end() iterator will
2633 /// point to the added case.
2634 void addCase(IntegersSubset& OnVal, BasicBlock *Dest);
2635
2636 /// removeCase - This method removes the specified case and its successor
2637 /// from the switch instruction. Note that this operation may reorder the
2638 /// remaining cases at index idx and above.
2639 /// Note:
2640 /// This action invalidates iterators for all cases following the one removed,
2641 /// including the case_end() iterator.
2642 void removeCase(CaseIt& i);
2643
2644 unsigned getNumSuccessors() const { return getNumOperands()/2; }
2645 BasicBlock *getSuccessor(unsigned idx) const {
2646 assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
2647 return cast(getOperand(idx*2+1));
2648 }
2649 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
2650 assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
2651 setOperand(idx*2+1, (Value*)NewSucc);
2652 }
2653
2654 uint16_t hash() const {
2655 uint32_t NumberOfCases = (uint32_t)getNumCases();
2656 uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
2657 for (ConstCaseIt i = case_begin(), e = case_end();
2658 i != e; ++i) {
2659 uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
2660 Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
2661 }
2662 return Hash;
2663 }
2664
2665 // Case iterators definition.
2666
2667 template
2668 class SubsetsItTy, class BasicBlockTy>
2488 template tTy, class BasicBlockTy>
26692489 class CaseIteratorT {
26702490 protected:
26712491
26722492 SwitchInstTy *SI;
26732493 unsigned Index;
2674 SubsetsItTy SubsetIt;
2494
2495 public:
2496
2497 typedef CaseIteratorT Self;
26752498
26762499 /// Initializes case iterator for given SwitchInst and for given
26772500 /// case number.
2678 friend class SwitchInst;
2679 CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex,
2680 SubsetsItTy CaseValueIt) {
2501 CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
26812502 this->SI = SI;
2682 Index = SuccessorIndex;
2683 this->SubsetIt = CaseValueIt;
2503 Index = CaseNum;
26842504 }
2685
2686 public:
2687 typedef typename SubsetsItTy::reference IntegersSubsetRef;
2688 typedef CaseIteratorT
2689 SubsetsItTy, BasicBlockTy> Self;
2690
2691 CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
2692 this->SI = SI;
2693 Index = CaseNum;
2694 SubsetIt = SI->TheSubsets.begin();
2695 std::advance(SubsetIt, CaseNum);
2696 }
2697
26982505
26992506 /// Initializes case iterator for given SwitchInst and for given
27002507 /// TerminatorInst's successor index.
27092516 /// Resolves case value for current case.
27102517 ConstantIntTy *getCaseValue() {
27112518 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2712 IntegersSubsetRef CaseRanges = *SubsetIt;
2713
2714 // FIXME: Currently we work with ConstantInt based cases.
2715 // So return CaseValue as ConstantInt.
2716 return CaseRanges.getSingleNumber(0).toConstantInt();
2717 }
2718
2719 /// Resolves case value for current case.
2720 IntegersSubsetRef getCaseValueEx() {
2721 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2722 return *SubsetIt;
2519 return reinterpret_cast(SI->getOperand(2 + Index*2));
27232520 }
27242521
27252522 /// Resolves successor for current case.
27452542 // Note: Index == getNumCases() means end().
27462543 assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
27472544 ++Index;
2748 if (Index == 0)
2749 SubsetIt = SI->TheSubsets.begin();
2750 else
2751 ++SubsetIt;
27522545 return *this;
27532546 }
27542547 Self operator++(int) {
27602553 // Check index correctness after decrement.
27612554 // Note: Index == getNumCases() means end().
27622555 // Also allow "-1" iterator here. That will became valid after ++.
2763 unsigned NumCases = SI->getNumCases();
2764 assert((Index == 0 || Index-1 <= NumCases) &&
2556 assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
27652557 "Index out the number of cases.");
27662558 --Index;
2767 if (Index == NumCases) {
2768 SubsetIt = SI->TheSubsets.end();
2769 return *this;
2770 }
2771
2772 if (Index != -1U)
2773 --SubsetIt;
2774
27752559 return *this;
27762560 }
27772561 Self operator--(int) {
27892573 }
27902574 };
27912575
2792 class CaseIt : public CaseIteratorT
2793 SubsetsIt, BasicBlock> {
2794 typedef CaseIteratorT
2795 ParentTy;
2796
2797 protected:
2798 friend class SwitchInst;
2799 CaseIt(SwitchInst *SI, unsigned CaseNum, SubsetsIt SubsetIt) :
2800 ParentTy(SI, CaseNum, SubsetIt) {}
2801
2802 void updateCaseValueOperand(IntegersSubset& V) {
2803 SI->setOperand(2 + Index*2, reinterpret_cast((Constant*)V));
2804 }
2576 typedef CaseIteratorT
2577 ConstCaseIt;
2578
2579 class CaseIt : public CaseIteratorT {
2580
2581 typedef CaseIteratorT ParentTy;
28052582
28062583 public:
28072584
2585 CaseIt(const ParentTy& Src) : ParentTy(Src) {}
28082586 CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
2809
2810 CaseIt(const ParentTy& Src) : ParentTy(Src) {}
28112587
28122588 /// Sets the new value for current case.
28132589 void setValue(ConstantInt *V) {
28142590 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2815 IntegersSubsetToBB Mapping;
2816 // FIXME: Currently we work with ConstantInt based cases.
2817 // So inititalize IntItem container directly from ConstantInt.
2818 Mapping.add(IntItem::fromConstantInt(V));
2819 *SubsetIt = Mapping.getCase();
2820 updateCaseValueOperand(*SubsetIt);
2821 }
2822
2823 /// Sets the new value for current case.
2824 void setValueEx(IntegersSubset& V) {
2825 assert(Index < SI->getNumCases() && "Index out the number of cases.");
2826 *SubsetIt = V;
2827 updateCaseValueOperand(*SubsetIt);
2591 SI->setOperand(2 + Index*2, reinterpret_cast(V));
28282592 }
28292593
28302594 /// Sets the new successor for current case.
28332597 }
28342598 };
28352599
2600 static SwitchInst *Create(Value *Value, BasicBlock *Default,
2601 unsigned NumCases, Instruction *InsertBefore = 0) {
2602 return new SwitchInst(Value, Default, NumCases, InsertBefore);
2603 }
2604 static SwitchInst *Create(Value *Value, BasicBlock *Default,
2605 unsigned NumCases, BasicBlock *InsertAtEnd) {
2606 return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
2607 }
2608
2609 ~SwitchInst();
2610
2611 /// Provide fast operand accessors
2612 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2613
2614 // Accessor Methods for Switch stmt
2615 Value *getCondition() const { return getOperand(0); }
2616 void setCondition(Value *V) { setOperand(0, V); }
2617
2618 BasicBlock *getDefaultDest() const {
2619 return cast(getOperand(1));
2620 }
2621
2622 void setDefaultDest(BasicBlock *DefaultCase) {
2623 setOperand(1, reinterpret_cast(DefaultCase));
2624 }
2625
2626 /// getNumCases - return the number of 'cases' in this switch instruction,
2627 /// except the default case
2628 unsigned getNumCases() const {
2629 return getNumOperands()/2 - 1;
2630 }
2631
2632 /// Returns a read/write iterator that points to the first
2633 /// case in SwitchInst.
2634 CaseIt case_begin() {
2635 return CaseIt(this, 0);
2636 }
2637 /// Returns a read-only iterator that points to the first
2638 /// case in the SwitchInst.
2639 ConstCaseIt case_begin() const {
2640 return ConstCaseIt(this, 0);
2641 }
2642
2643 /// Returns a read/write iterator that points one past the last
2644 /// in the SwitchInst.
2645 CaseIt case_end() {
2646 return CaseIt(this, getNumCases());
2647 }
2648 /// Returns a read-only iterator that points one past the last
2649 /// in the SwitchInst.
2650 ConstCaseIt case_end() const {
2651 return ConstCaseIt(this, getNumCases());
2652 }
2653 /// Returns an iterator that points to the default case.
2654 /// Note: this iterator allows to resolve successor only. Attempt
2655 /// to resolve case value causes an assertion.
2656 /// Also note, that increment and decrement also causes an assertion and
2657 /// makes iterator invalid.
2658 CaseIt case_default() {
2659 return CaseIt(this, DefaultPseudoIndex);
2660 }
2661 ConstCaseIt case_default() const {
2662 return ConstCaseIt(this, DefaultPseudoIndex);
2663 }
2664
2665 /// findCaseValue - Search all of the case values for the specified constant.
2666 /// If it is explicitly handled, return the case iterator of it, otherwise
2667 /// return default case iterator to indicate
2668 /// that it is handled by the default handler.
2669 CaseIt findCaseValue(const ConstantInt *C) {
2670 for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
2671 if (i.getCaseValue() == C)
2672 return i;
2673 return case_default();
2674 }
2675 ConstCaseIt findCaseValue(const ConstantInt *C) const {
2676 for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
2677 if (i.getCaseValue() == C)
2678 return i;
2679 return case_default();
2680 }
2681
2682 /// findCaseDest - Finds the unique case value for a given successor. Returns
2683 /// null if the successor is not found, not unique, or is the default case.
2684 ConstantInt *findCaseDest(BasicBlock *BB) {
2685 if (BB == getDefaultDest()) return NULL;
2686
2687 ConstantInt *CI = NULL;
2688 for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
2689 if (i.getCaseSuccessor() == BB) {
2690 if (CI) return NULL; // Multiple cases lead to BB.
2691 else CI = i.getCaseValue();
2692 }
2693 }
2694 return CI;
2695 }
2696
2697 /// addCase - Add an entry to the switch instruction...
2698 /// Note:
2699 /// This action invalidates case_end(). Old case_end() iterator will
2700 /// point to the added case.
2701 void addCase(ConstantInt *OnVal, BasicBlock *Dest);
2702
2703 /// removeCase - This method removes the specified case and its successor
2704 /// from the switch instruction. Note that this operation may reorder the
2705 /// remaining cases at index idx and above.
2706 /// Note:
2707 /// This action invalidates iterators for all cases following the one removed,
2708 /// including the case_end() iterator.
2709 void removeCase(CaseIt i);
2710
2711 unsigned getNumSuccessors() const { return getNumOperands()/2; }
2712 BasicBlock *getSuccessor(unsigned idx) const {
2713 assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
2714 return cast(getOperand(idx*2+1));
2715 }
2716 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
2717 assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
2718 setOperand(idx*2+1, (Value*)NewSucc);
2719 }
2720
28362721 // Methods for support type inquiry through isa, cast, and dyn_cast:
2837
28382722 static inline bool classof(const Instruction *I) {
28392723 return I->getOpcode() == Instruction::Switch;
28402724 }
+0
-540
include/llvm/Support/IntegersSubset.h less more
None //===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// @file
10 /// This file contains class that implements constant set of ranges:
11 /// [,...,]. Initially, this class was created for
12 /// SwitchInst and was used for case value representation that may contain
13 /// multiple ranges for a single successor.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
18 #define LLVM_SUPPORT_INTEGERSSUBSET_H
19
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/LLVMContext.h"
23 #include
24
25 namespace llvm {
26
27 // The IntItem is a wrapper for APInt.
28 // 1. It determines sign of integer, it allows to use
29 // comparison operators >,<,>=,<=, and as result we got shorter and cleaner
30 // constructions.
31 // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
32 // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
33 // It allows to provide SwitchInst methods that works with ConstantInt for
34 // non-updated passes. And it allows to use APInt interface for new methods.
35 // 4. IntItem can be easily replaced with APInt.
36
37 // The set of macros that allows to propagate APInt operators to the IntItem.
38
39 #define INT_ITEM_DEFINE_COMPARISON(op,func) \
40 bool operator op (const APInt& RHS) const { \
41 return getAPIntValue().func(RHS); \
42 }
43
44 #define INT_ITEM_DEFINE_UNARY_OP(op) \
45 IntItem operator op () const { \
46 APInt res = op(getAPIntValue()); \
47 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
48 return IntItem(cast(NewVal)); \
49 }
50
51 #define INT_ITEM_DEFINE_BINARY_OP(op) \
52 IntItem operator op (const APInt& RHS) const { \
53 APInt res = getAPIntValue() op RHS; \
54 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
55 return IntItem(cast(NewVal)); \
56 }
57
58 #define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
59 IntItem& operator op (const APInt& RHS) {\
60 APInt res = getAPIntValue();\
61 res op RHS; \
62 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
63 ConstantIntVal = cast(NewVal); \
64 return *this; \
65 }
66
67 #define INT_ITEM_DEFINE_PREINCDEC(op) \
68 IntItem& operator op () { \
69 APInt res = getAPIntValue(); \
70 op(res); \
71 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
72 ConstantIntVal = cast(NewVal); \
73 return *this; \
74 }
75
76 #define INT_ITEM_DEFINE_POSTINCDEC(op) \
77 IntItem& operator op (int) { \
78 APInt res = getAPIntValue();\
79 op(res); \
80 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
81 OldConstantIntVal = ConstantIntVal; \
82 ConstantIntVal = cast(NewVal); \
83 return IntItem(OldConstantIntVal); \
84 }
85
86 #define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
87 RetTy operator op (IntTy RHS) const { \
88 return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
89 }
90
91 class IntItem {
92 ConstantInt *ConstantIntVal;
93 const APInt* APIntVal;
94 IntItem(const ConstantInt *V) :
95 ConstantIntVal(const_cast(V)),
96 APIntVal(&ConstantIntVal->getValue()){}
97 const APInt& getAPIntValue() const {
98 return *APIntVal;
99 }
100 public:
101
102 IntItem() {}
103
104 operator const APInt&() const {
105 return getAPIntValue();
106 }
107
108 // Propagate APInt operators.
109 // Note, that
110 // /,/=,>>,>>= are not implemented in APInt.
111 // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
112
113 INT_ITEM_DEFINE_COMPARISON(<, ult)
114 INT_ITEM_DEFINE_COMPARISON(>, ugt)
115 INT_ITEM_DEFINE_COMPARISON(<=, ule)
116 INT_ITEM_DEFINE_COMPARISON(>=, uge)
117
118 INT_ITEM_DEFINE_COMPARISON(==, eq)
119 INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
120
121 INT_ITEM_DEFINE_COMPARISON(!=, ne)
122 INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
123
124 INT_ITEM_DEFINE_BINARY_OP(*)
125 INT_ITEM_DEFINE_BINARY_OP(+)
126 INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
127 INT_ITEM_DEFINE_BINARY_OP(-)
128 INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
129 INT_ITEM_DEFINE_BINARY_OP(<<)
130 INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
131 INT_ITEM_DEFINE_BINARY_OP(&)
132 INT_ITEM_DEFINE_BINARY_OP(^)
133 INT_ITEM_DEFINE_BINARY_OP(|)
134
135 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
136 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
137 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
138 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
139 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
140 INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
141
142 // Special case for <<=
143 IntItem& operator <<= (unsigned RHS) {
144 APInt res = getAPIntValue();
145 res <<= RHS;
146 Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
147 ConstantIntVal = cast(NewVal);
148 return *this;
149 }
150
151 INT_ITEM_DEFINE_UNARY_OP(-)
152 INT_ITEM_DEFINE_UNARY_OP(~)
153
154 INT_ITEM_DEFINE_PREINCDEC(++)
155 INT_ITEM_DEFINE_PREINCDEC(--)
156
157 // The set of workarounds, since currently we use ConstantInt implemented
158 // integer.
159
160 static IntItem fromConstantInt(const ConstantInt *V) {
161 return IntItem(V);
162 }
163 static IntItem fromType(Type* Ty, const APInt& V) {
164 ConstantInt *C = cast(ConstantInt::get(Ty, V));
165 return fromConstantInt(C);
166 }
167 static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
168 ConstantInt *C = cast(ConstantInt::get(
169 LikeThis.ConstantIntVal->getContext(), V));
170 return fromConstantInt(C);
171 }
172 ConstantInt *toConstantInt() const {
173 return ConstantIntVal;
174 }
175 };
176
177 template
178 class IntRange {
179 protected:
180 IntType Low;
181 IntType High;
182 bool IsEmpty : 1;
183 bool IsSingleNumber : 1;
184
185 public:
186 typedef IntRange self;
187 typedef std::pair SubRes;
188
189 IntRange() : IsEmpty(true) {}
190 IntRange(const self &RHS) :
191 Low(RHS.Low), High(RHS.High),
192 IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
193 IntRange(const IntType &C) :
194 Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
195
196 IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
197 IsEmpty(false), IsSingleNumber(Low == High) {}
198
199 bool isEmpty() const { return IsEmpty; }
200 bool isSingleNumber() const { return IsSingleNumber; }
201
202 const IntType& getLow() const {
203 assert(!IsEmpty && "Range is empty.");
204 return Low;
205 }
206 const IntType& getHigh() const {
207 assert(!IsEmpty && "Range is empty.");
208 return High;
209 }
210
211 bool operator<(const self &RHS) const {
212 assert(!IsEmpty && "Left range is empty.");
213 assert(!RHS.IsEmpty && "Right range is empty.");
214 if (Low == RHS.Low) {
215 if (High > RHS.High)
216 return true;
217 return false;
218 }
219 if (Low < RHS.Low)
220 return true;
221 return false;
222 }
223
224 bool operator==(const self &RHS) const {
225 assert(!IsEmpty && "Left range is empty.");
226 assert(!RHS.IsEmpty && "Right range is empty.");
227 return Low == RHS.Low && High == RHS.High;
228 }
229
230 bool operator!=(const self &RHS) const {
231 return !operator ==(RHS);
232 }
233
234 static bool LessBySize(const self &LHS, const self &RHS) {
235 return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
236 }
237
238 bool isInRange(const IntType &IntVal) const {
239 assert(!IsEmpty && "Range is empty.");
240 return IntVal >= Low && IntVal <= High;
241 }
242
243 SubRes sub(const self &RHS) const {
244 SubRes Res;
245
246 // RHS is either more global and includes this range or
247 // if it doesn't intersected with this range.
248 if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
249
250 // If RHS more global (it is enough to check
251 // only one border in this case.
252 if (RHS.isInRange(Low))
253 return std::make_pair(self(Low, High), self());
254
255 return Res;
256 }
257
258 if (Low < RHS.Low) {
259 Res.first.Low = Low;
260 IntType NewHigh = RHS.Low;
261 --NewHigh;
262 Res.first.High = NewHigh;
263 }
264 if (High > RHS.High) {
265 IntType NewLow = RHS.High;
266 ++NewLow;
267 Res.second.Low = NewLow;
268 Res.second.High = High;
269 }
270 return Res;
271 }
272 };
273
274 //===----------------------------------------------------------------------===//
275 /// IntegersSubsetGeneric - class that implements the subset of integers. It
276 /// consists from ranges and single numbers.
277 template
278 class IntegersSubsetGeneric {
279 public:
280 // Use Chris Lattner idea, that was initially described here:
281 // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
282 // In short, for more compact memory consumption we can store flat
283 // numbers collection, and define range as pair of indices.
284 // In that case we can safe some memory on 32 bit machines.
285 typedef std::vector FlatCollectionTy;
286 typedef std::pair RangeLinkTy;
287 typedef std::vector RangeLinksTy;
288 typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
289
290 typedef IntegersSubsetGeneric self;
291
292 protected:
293
294 FlatCollectionTy FlatCollection;
295 RangeLinksTy RangeLinks;
296
297 bool IsSingleNumber;
298 bool IsSingleNumbersOnly;
299
300 public:
301
302 template
303 explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
304 assert(Links.size() && "Empty ranges are not allowed.");
305
306 // In case of big set of single numbers consumes additional RAM space,
307 // but allows to avoid additional reallocation.
308 FlatCollection.reserve(Links.size() * 2);
309 RangeLinks.reserve(Links.size());
310 IsSingleNumbersOnly = true;
311 for (typename RangesCollectionTy::const_iterator i = Links.begin(),
312 e = Links.end(); i != e; ++i) {
313 RangeLinkTy RangeLink;
314 FlatCollection.push_back(i->getLow());
315 RangeLink.first = &FlatCollection.back();
316 if (i->getLow() != i->getHigh()) {
317 FlatCollection.push_back(i->getHigh());
318 IsSingleNumbersOnly = false;
319 }
320 RangeLink.second = &FlatCollection.back();
321 RangeLinks.push_back(RangeLink);
322 }
323 IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
324 }
325
326 IntegersSubsetGeneric(const self& RHS) {
327 *this = RHS;
328 }
329
330 self& operator=(const self& RHS) {
331 FlatCollection.clear();
332 RangeLinks.clear();
333 FlatCollection.reserve(RHS.RangeLinks.size() * 2);
334 RangeLinks.reserve(RHS.RangeLinks.size());
335 for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
336 i != e; ++i) {
337 RangeLinkTy RangeLink;
338 FlatCollection.push_back(*(i->first));
339 RangeLink.first = &FlatCollection.back();
340 if (i->first != i->second)
341 FlatCollection.push_back(*(i->second));
342 RangeLink.second = &FlatCollection.back();
343 RangeLinks.push_back(RangeLink);
344 }
345 IsSingleNumber = RHS.IsSingleNumber;
346 IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
347 return *this;
348 }
349
350 typedef IntRange Range;
351
352 /// Checks is the given constant satisfies this case. Returns
353 /// true if it equals to one of contained values or belongs to the one of
354 /// contained ranges.
355 bool isSatisfies(const IntTy &CheckingVal) const {
356 if (IsSingleNumber)
357 return FlatCollection.front() == CheckingVal;
358 if (IsSingleNumbersOnly)
359 return std::find(FlatCollection.begin(),
360 FlatCollection.end(),
361 CheckingVal) != FlatCollection.end();
362
363 for (size_t i = 0, e = getNumItems(); i < e; ++i) {
364 if (RangeLinks[i].first == RangeLinks[i].second) {
365 if (*RangeLinks[i].first == CheckingVal)
366 return true;
367 } else if (*RangeLinks[i].first <= CheckingVal &&
368 *RangeLinks[i].second >= CheckingVal)
369 return true;
370 }
371 return false;
372 }
373
374 /// Returns set's item with given index.
375 Range getItem(unsigned idx) const {
376 const RangeLinkTy &Link = RangeLinks[idx];
377 if (Link.first != Link.second)
378 return Range(*Link.first, *Link.second);
379 else
380 return Range(*Link.first);
381 }
382
383 /// Return number of items (ranges) stored in set.
384 size_t getNumItems() const {
385 return RangeLinks.size();
386 }
387
388 /// Returns true if whole subset contains single element.
389 bool isSingleNumber() const {
390 return IsSingleNumber;
391 }
392
393 /// Returns true if whole subset contains only single numbers, no ranges.
394 bool isSingleNumbersOnly() const {
395 return IsSingleNumbersOnly;
396 }
397
398 /// Does the same like getItem(idx).isSingleNumber(), but
399 /// works faster, since we avoid creation of temporary range object.
400 bool isSingleNumber(unsigned idx) const {
401 return RangeLinks[idx].first == RangeLinks[idx].second;
402 }
403
404 /// Returns set the size, that equals number of all values + sizes of all
405 /// ranges.
406 /// Ranges set is considered as flat numbers collection.
407 /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
408 /// for range [<0>, <1>, <5>] the size will 3
409 unsigned getSize() const {
410 APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
411 for (size_t i = 0, e = getNumItems(); i != e; ++i) {
412 const APInt Low = getItem(i).getLow();
413 const APInt High = getItem(i).getHigh();
414 APInt S = High - Low + 1;
415 sz += S;
416 }
417 return sz.getZExtValue();
418 }
419
420 /// Allows to access single value even if it belongs to some range.
421 /// Ranges set is considered as flat numbers collection.
422 /// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
423 /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
424 APInt getSingleValue(unsigned idx) const {
425 APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
426 for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
427 const APInt Low = getItem(i).getLow();
428 const APInt High = getItem(i).getHigh();
429 APInt S = High - Low + 1;
430 APInt oldSz = sz;
431 sz += S;
432 if (sz.ugt(idx)) {
433 APInt Res = Low;
434 APInt Offset(oldSz.getBitWidth(), idx);
435 Offset -= oldSz;
436 Res += Offset;
437 return Res;
438 }
439 }
440 assert(0 && "Index exceeds high border.");
441 return sz;
442 }
443
444 /// Does the same as getSingleValue, but works only if subset contains
445 /// single numbers only.
446 const IntTy& getSingleNumber(unsigned idx) const {
447 assert(IsSingleNumbersOnly && "This method works properly if subset "
448 "contains single numbers only.");
449 return FlatCollection[idx];
450 }
451 };
452
453 //===----------------------------------------------------------------------===//
454 /// IntegersSubset - currently is extension of IntegersSubsetGeneric
455 /// that also supports conversion to/from Constant* object.
456 class IntegersSubset : public IntegersSubsetGeneric {
457
458 typedef IntegersSubsetGeneric ParentTy;
459
460 Constant *Holder;
461
462 static unsigned getNumItemsFromConstant(Constant *C) {
463 return cast(C->getType())->getNumElements();
464 }
465
466 static Range getItemFromConstant(Constant *C, unsigned idx) {
467 const Constant *CV = C->getAggregateElement(idx);
468
469 unsigned NumEls = cast(CV->getType())->getNumElements();
470 switch (NumEls) {
471 case 1:
472 return Range(IntItem::fromConstantInt(
473 cast(CV->getAggregateElement(0U))),
474 IntItem::fromConstantInt(cast(
475 cast(CV->getAggregateElement(0U)))));
476 case 2:
477 return Range(IntItem::fromConstantInt(
478 cast(CV->getAggregateElement(0U))),
479 IntItem::fromConstantInt(
480 cast(CV->getAggregateElement(1))));
481 default:
482 assert(0 && "Only pairs and single numbers are allowed here.");
483 return Range();
484 }
485 }
486
487 std::vector rangesFromConstant(Constant *C) {
488 unsigned NumItems = getNumItemsFromConstant(C);
489 std::vector r;
490 r.reserve(NumItems);
491 for (unsigned i = 0, e = NumItems; i != e; ++i)
492 r.push_back(getItemFromConstant(C, i));
493 return r;
494 }
495
496 public:
497
498 explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
499 Holder(C) {}
500
501 IntegersSubset(const IntegersSubset& RHS) :
502 ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
503 Holder(RHS.Holder) {}
504
505 template
506 explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
507 std::vector Elts;
508 Elts.reserve(Src.size());
509 for (typename RangesCollectionTy::const_iterator i = Src.begin(),
510 e = Src.end(); i != e; ++i) {
511 const Range &R = *i;
512 std::vector r;
513 if (R.isSingleNumber()) {
514 r.reserve(2);
515 // FIXME: Since currently we have ConstantInt based numbers
516 // use hack-conversion of IntItem to ConstantInt
517 r.push_back(R.getLow().toConstantInt());
518 r.push_back(R.getHigh().toConstantInt());
519 } else {
520 r.reserve(1);
521 r.push_back(R.getLow().toConstantInt());
522 }
523 Constant *CV = ConstantVector::get(r);
524 Elts.push_back(CV);
525 }
526 ArrayType *ArrTy =
527 ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
528 Holder = ConstantArray::get(ArrTy, Elts);
529 }
530
531 operator Constant*() { return Holder; }
532 operator const Constant*() const { return Holder; }
533 Constant *operator->() { return Holder; }
534 const Constant *operator->() const { return Holder; }
535 };
536
537 }
538
539 #endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
+0
-588
include/llvm/Support/IntegersSubsetMapping.h less more
None //===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// @file
10 /// IntegersSubsetMapping is mapping from A to B, where
11 /// Items in A is subsets of integers,
12 /// Items in B some pointers (Successors).
13 /// If user which to add another subset for successor that is already
14 /// exists in mapping, IntegersSubsetMapping merges existing subset with
15 /// added one.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
20 #define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
21
22 #include "llvm/Support/IntegersSubset.h"
23 #include
24 #include
25 #include
26
27 namespace llvm {
28
29 template
30 class IntegersSubsetTy = IntegersSubset,
31 class IntTy = IntItem>
32 class IntegersSubsetMapping {
33 // FIXME: To much similar iterators typedefs, similar names.
34 // - Rename RangeIterator to the cluster iterator.
35 // - Remove unused "add" methods.
36 // - Class contents needs cleaning.
37 public:
38
39 typedef IntRange RangeTy;
40
41 struct RangeEx : public RangeTy {
42 RangeEx() : Weight(1) {}
43 RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
44 RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
45 RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
46 RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
47 RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
48 RangeTy(L, H), Weight(W) {}
49 unsigned Weight;
50 };
51
52 typedef std::pair Cluster;
53
54 typedef std::list RangesCollection;
55 typedef typename RangesCollection::iterator RangesCollectionIt;
56 typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
57 typedef IntegersSubsetMapping self;
58
59 protected:
60
61 typedef std::list CaseItems;
62 typedef typename CaseItems::iterator CaseItemIt;
63 typedef typename CaseItems::const_iterator CaseItemConstIt;
64
65 // TODO: Change unclean CRS prefixes to SubsetMap for example.
66 typedef std::map CRSMap;
67 typedef typename CRSMap::iterator CRSMapIt;
68
69 struct ClustersCmp {
70 bool operator()(const Cluster &C1, const Cluster &C2) {
71 return C1.first < C2.first;
72 }
73 };
74
75 CaseItems Items;
76 bool Sorted;
77
78 bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
79 return LItem->first.getHigh() >= RItem->first.getLow();
80 }
81
82 bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
83 if (LItem->second != RItem->second) {
84 assert(!isIntersected(LItem, RItem) &&
85 "Intersected items with different successors!");
86 return false;
87 }
88 APInt RLow = RItem->first.getLow();
89 if (RLow != APInt::getNullValue(RLow.getBitWidth()))
90 --RLow;
91 return LItem->first.getHigh() >= RLow;
92 }
93
94 void sort() {
95 if (!Sorted) {
96 std::vector clustersVector;
97 clustersVector.reserve(Items.size());
98 clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
99 std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
100 Items.clear();
101 Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
102 Sorted = true;
103 }
104 }
105
106 enum DiffProcessState {
107 L_OPENED,
108 INTERSECT_OPENED,
109 R_OPENED,
110 ALL_IS_CLOSED
111 };
112
113 class DiffStateMachine {
114
115 DiffProcessState State;
116 IntTy OpenPt;
117 SuccessorClass *CurrentLSuccessor;
118 SuccessorClass *CurrentRSuccessor;
119
120 self *LeftMapping;
121 self *IntersectionMapping;
122 self *RightMapping;
123
124 public:
125
126 typedef
127 IntegersSubsetMapping MappingTy;
128
129 DiffStateMachine(MappingTy *L,
130 MappingTy *Intersection,
131 MappingTy *R) :
132 State(ALL_IS_CLOSED),
133 LeftMapping(L),
134 IntersectionMapping(Intersection),
135 RightMapping(R)
136 {}
137
138 void onLOpen(const IntTy &Pt, SuccessorClass *S) {
139 switch (State) {
140 case R_OPENED:
141 if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
142 RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
143 State = INTERSECT_OPENED;
144 break;
145 case ALL_IS_CLOSED:
146 State = L_OPENED;
147 break;
148 default:
149 assert(0 && "Got unexpected point.");
150 break;
151 }
152 CurrentLSuccessor = S;
153 OpenPt = Pt;
154 }
155
156 void onLClose(const IntTy &Pt) {
157 switch (State) {
158 case L_OPENED:
159 assert(Pt >= OpenPt &&
160 "Subset is not sorted or contains overlapped ranges");
161 if (LeftMapping)
162 LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
163 State = ALL_IS_CLOSED;
164 break;
165 case INTERSECT_OPENED:
166 if (IntersectionMapping)
167 IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
168 OpenPt = Pt + 1;
169 State = R_OPENED;
170 break;
171 default:
172 assert(0 && "Got unexpected point.");
173 break;
174 }
175 }
176
177 void onROpen(const IntTy &Pt, SuccessorClass *S) {
178 switch (State) {
179 case L_OPENED:
180 if (Pt > OpenPt && LeftMapping)
181 LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
182 State = INTERSECT_OPENED;
183 break;
184 case ALL_IS_CLOSED:
185 State = R_OPENED;
186 break;
187 default:
188 assert(0 && "Got unexpected point.");
189 break;
190 }
191 CurrentRSuccessor = S;
192 OpenPt = Pt;
193 }
194
195 void onRClose(const IntTy &Pt) {
196 switch (State) {
197 case R_OPENED:
198 assert(Pt >= OpenPt &&
199 "Subset is not sorted or contains overlapped ranges");
200 if (RightMapping)
201 RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
202 State = ALL_IS_CLOSED;
203 break;
204 case INTERSECT_OPENED:
205 if (IntersectionMapping)
206 IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
207 OpenPt = Pt + 1;
208 State = L_OPENED;
209 break;
210 default:
211 assert(0 && "Got unexpected point.");
212 break;
213 }
214 }
215
216 void onLROpen(const IntTy &Pt,
217 SuccessorClass *LS,
218 SuccessorClass *RS) {
219 switch (State) {
220 case ALL_IS_CLOSED:
221 State = INTERSECT_OPENED;
222 break;
223 default:
224 assert(0 && "Got unexpected point.");
225 break;
226 }
227 CurrentLSuccessor = LS;
228 CurrentRSuccessor = RS;
229 OpenPt = Pt;
230 }
231
232 void onLRClose(const IntTy &Pt) {
233 switch (State) {
234 case INTERSECT_OPENED:
235 if (IntersectionMapping)
236 IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
237 State = ALL_IS_CLOSED;
238 break;
239 default:
240 assert(0 && "Got unexpected point.");
241 break;
242 }
243 }
244
245 bool isLOpened() { return State == L_OPENED; }
246 bool isROpened() { return State == R_OPENED; }
247 };
248
249 public:
250
251 // Don't public CaseItems itself. Don't allow edit the Items directly.
252 // Just present the user way to iterate over the internal collection
253 // sharing iterator, begin() and end(). Editing should be controlled by
254 // factory.
255 typedef CaseItemIt RangeIterator;
256
257 typedef std::pair Case;
258 typedef std::list Cases;
259 typedef typename Cases::iterator CasesIt;
260
261 IntegersSubsetMapping() {
262 Sorted = false;
263 }
264
265 bool verify() {
266 RangeIterator DummyErrItem;
267 return verify(DummyErrItem);
268 }
269
270 bool verify(RangeIterator& errItem) {
271 if (Items.empty())
272 return true;
273 sort();
274 for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
275 j != e; i = j++) {
276 if (isIntersected(i, j) && i->second != j->second) {
277 errItem = j;
278 return false;
279 }
280 }
281 return true;
282 }
283
284 bool isOverlapped(self &RHS) {
285 if (Items.empty() || RHS.empty())
286 return true;
287
288 for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
289 el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
290
291 const RangeTy &LRange = L->first;
292 const RangeTy &RRange = R->first;
293
294 if (LRange.getLow() > RRange.getLow()) {
295 if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
296 ++R;
297 else
298 return true;
299 } else if (LRange.getLow() < RRange.getLow()) {
300 if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
301 ++L;
302 else
303 return true;
304 } else // iRange.getLow() == jRange.getLow()
305 return true;
306 }
307 return false;
308 }
309
310
311 void optimize() {
312 if (Items.size() < 2)
313 return;
314 sort();
315 CaseItems OldItems = Items;
316 Items.clear();
317 const IntTy *Low = &OldItems.begin()->first.getLow();
318 const IntTy *High = &OldItems.begin()->first.getHigh();
319 unsigned Weight = OldItems.begin()->first.Weight;
320 SuccessorClass *Successor = OldItems.begin()->second;
321 for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
322 j != e; i = j++) {
323 if (isJoinable(i, j)) {
324 const IntTy *CurHigh = &j->first.getHigh();
325 Weight += j->first.Weight;
326 if (*CurHigh > *High)
327 High = CurHigh;
328 } else {
329 RangeEx R(*Low, *High, Weight);
330 add(R, Successor);
331 Low = &j->first.getLow();
332 High = &j->first.getHigh();
333 Weight = j->first.Weight;
334 Successor = j->second;
335 }
336 }
337 RangeEx R(*Low, *High, Weight);
338 add(R, Successor);
339 // We recollected the Items, but we kept it sorted.
340 Sorted = true;
341 }
342
343 /// Adds a constant value.
344 void add(const IntTy &C, SuccessorClass *S = 0) {
345 RangeTy R(C);
346 add(R, S);
347 }
348
349 /// Adds a range.
350 void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
351 RangeTy R(Low, High);
352 add(R, S);
353 }
354 void add(const RangeTy &R, SuccessorClass *S = 0) {
355 RangeEx REx = R;
356 add(REx, S);
357 }
358 void add(const RangeEx &R, SuccessorClass *S = 0) {
359 Items.push_back(std::make_pair(R, S));
360 Sorted = false;
361 }
362
363 /// Adds all ranges and values from given ranges set to the current
364 /// mapping.
365 void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
366 unsigned Weight = 0) {
367 unsigned ItemWeight = 1;
368 if (Weight)
369 // Weight is associated with CRS, for now we perform a division to
370 // get the weight for each item.
371 ItemWeight = Weight / CRS.getNumItems();
372 for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
373 RangeTy R = CRS.getItem(i);
374 RangeEx REx(R, ItemWeight);
375 add(REx, S);
376 }
377 }
378
379 void add(self& RHS) {
380 Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
381 }
382
383 void add(self& RHS, SuccessorClass *S) {
384 for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
385 add(i->first, S);
386 }
387
388 void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
389 for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
390 add(*i, S);
391 }
392
393 /// Removes items from set.
394 void removeItem(RangeIterator i) { Items.erase(i); }
395
396 /// Moves whole case from current mapping to the NewMapping object.
397 void detachCase(self& NewMapping, SuccessorClass *Succ) {
398 for (CaseItemIt i = Items.begin(); i != Items.end();)
399 if (i->second == Succ) {
400 NewMapping.add(i->first, i->second);
401 Items.erase(i++);
402 } else
403 ++i;
404 }
405
406 /// Removes all clusters for given successor.
407 void removeCase(SuccessorClass *Succ) {
408 for (CaseItemIt i = Items.begin(); i != Items.end();)
409 if (i->second == Succ) {
410 Items.erase(i++);
411 } else
412 ++i;
413 }
414
415 /// Find successor that satisfies given value.
416 SuccessorClass *findSuccessor(const IntTy& Val) {
417 for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
418 if (i->first.isInRange(Val))
419 return i->second;
420 }
421 return 0;
422 }
423
424 /// Calculates the difference between this mapping and RHS.
425 /// THIS without RHS is placed into LExclude,
426 /// RHS without THIS is placed into RExclude,
427 /// THIS intersect RHS is placed into Intersection.
428 void diff(self *LExclude, self *Intersection, self *RExclude,
429 const self& RHS) {
430
431 DiffStateMachine Machine(LExclude, Intersection, RExclude);
432
433 CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
434 while (L != Items.end() && R != RHS.Items.end()) {
435 const Cluster &LCluster = *L;
436 const RangeEx &LRange = LCluster.first;
437 const Cluster &RCluster = *R;
438 const RangeEx &RRange = RCluster.first;
439
440 if (LRange.getHigh() < RRange.getLow()) {
441 Machine.onLOpen(LRange.getLow(), LCluster.second);
442 Machine.onLClose(LRange.getHigh());
443 ++L;
444 continue;
445 }
446
447 if (LRange.getLow() > RRange.getHigh()) {
448 Machine.onROpen(RRange.getLow(), RCluster.second);
449 Machine.onRClose(RRange.getHigh());
450 ++R;
451 continue;
452 }
453
454 if (LRange.getLow() < RRange.getLow()) {
455 // May be opened in previous iteration.
456 if (!Machine.isLOpened())
457 Machine.onLOpen(LRange.getLow(), LCluster.second);
458 Machine.onROpen(RRange.getLow(), RCluster.second);
459 }
460 else if (RRange.getLow() < LRange.getLow()) {
461 if (!Machine.isROpened())
462 Machine.onROpen(RRange.getLow(), RCluster.second);
463 Machine.onLOpen(LRange.getLow(), LCluster.second);
464 }
465 else
466 Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
467
468 if (LRange.getHigh() < RRange.getHigh()) {
469 Machine.onLClose(LRange.getHigh());
470 ++L;
471 while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
472 Machine.onLOpen(L->first.getLow(), L->second);
473 Machine.onLClose(L->first.getHigh());
474 ++L;
475 }
476 }
477 else if (RRange.getHigh() < LRange.getHigh()) {
478 Machine.onRClose(RRange.getHigh());
479 ++R;
480 while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
481 Machine.onROpen(R->first.getLow(), R->second);
482 Machine.onRClose(R->first.getHigh());
483 ++R;
484 }
485 }
486 else {
487 Machine.onLRClose(LRange.getHigh());
488 ++L;
489 ++R;
490 }
491 }
492
493 if (L != Items.end()) {
494 if (Machine.isLOpened()) {
495 Machine.onLClose(L->first.getHigh());
496 ++L;
497 }
498 if (LExclude)
499 while (L != Items.end()) {
500 LExclude->add(L->first, L->second);
501 ++L;
502 }
503 } else if (R != RHS.Items.end()) {
504 if (Machine.isROpened()) {
505 Machine.onRClose(R->first.getHigh());
506 ++R;
507 }
508 if (RExclude)
509 while (R != RHS.Items.end()) {
510 RExclude->add(R->first, R->second);
511 ++R;
512 }
513 }
514 }
515
516 /// Builds the finalized case objects.
517 void getCases(Cases& TheCases, bool PreventMerging = false) {
518 //FIXME: PreventMerging is a temporary parameter.
519 //Currently a set of passes is still knows nothing about
520 //switches with case ranges, and if these passes meet switch
521 //with complex case that crashs the application.
522 if (PreventMerging) {
523 for (RangeIterator i = this->begin(); i != this->end(); ++i) {
524 RangesCollection SingleRange;
525 SingleRange.push_back(i->first);
526 TheCases.push_back(std::make_pair(i->second,
527 IntegersSubsetTy(SingleRange)));
528 }
529 return;
530 }
531 CRSMap TheCRSMap;
532 for (RangeIterator i = this->begin(); i != this->end(); ++i)
533 TheCRSMap[i->second].push_back(i->first);
534 for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
535 TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
536 }
537
538 /// Builds the finalized case objects ignoring successor values, as though
539 /// all ranges belongs to the same successor.
540 IntegersSubsetTy getCase() {
541 RangesCollection Ranges;
542 for (RangeIterator i = this->begin(); i != this->end(); ++i)
543 Ranges.push_back(i->first);
544 return IntegersSubsetTy(Ranges);
545 }
546
547 /// Returns pointer to value of case if it is single-numbered or 0
548 /// in another case.
549 const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
550 const IntTy* Res = 0;
551 for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
552 if (i->second == Succ) {
553 if (!i->first.isSingleNumber())
554 return 0;
555 if (Res)
556 return 0;
557 else
558 Res = &(i->first.getLow());
559 }
560 return Res;
561 }
562
563 /// Returns true if there is no ranges and values inside.
564 bool empty() const { return Items.empty(); }
565
566 void clear() {
567 Items.clear();
568 // Don't reset Sorted flag:
569 // 1. For empty mapping it matters nothing.
570 // 2. After first item will added Sorted flag will cleared.
571 }
572
573 // Returns number of clusters
574 unsigned size() const {
575 return Items.size();
576 }
577
578 RangeIterator begin() { return Items.begin(); }
579 RangeIterator end() { return Items.end(); }
580 };
581
582 class BasicBlock;
583 typedef IntegersSubsetMapping IntegersSubsetToBB;
584
585 }
586
587 #endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
24902490 case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
24912491 // Check magic
24922492 if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
2493 // New SwitchInst format with case ranges.
2493 // "New" SwitchInst format with case ranges. The changes to write this
2494 // format were reverted but we still recognize bitcode that uses it.
2495 // Hopefully someday we will have support for case ranges and can use
2496 // this format again.
24942497
24952498 Type *OpTy = getTypeByID(Record[1]);
24962499 unsigned ValueBitWidth = cast(OpTy)->getBitWidth();
25072510
25082511 unsigned CurIdx = 5;
25092512 for (unsigned i = 0; i != NumCases; ++i) {
2510 IntegersSubsetToBB CaseBuilder;
2513 SmallVector CaseVals;
25112514 unsigned NumItems = Record[CurIdx++];
25122515 for (unsigned ci = 0; ci != NumItems; ++ci) {
25132516 bool isSingleNumber = Record[CurIdx++];
25272530 APInt High =
25282531 ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
25292532 ValueBitWidth);
2530
2531 CaseBuilder.add(IntItem::fromType(OpTy, Low),
2532 IntItem::fromType(OpTy, High));
25332533 CurIdx += ActiveWords;
2534
2535 // FIXME: It is not clear whether values in the range should be
2536 // compared as signed or unsigned values. The partially
2537 // implemented changes that used this format in the past used
2538 // unsigned comparisons.
2539 for ( ; Low.ule(High); ++Low)
2540 CaseVals.push_back(ConstantInt::get(Context, Low));
25342541 } else
2535 CaseBuilder.add(IntItem::fromType(OpTy, Low));
2542 CaseVals.push_back(ConstantInt::get(Context, Low));
25362543 }
25372544 BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
2538 IntegersSubset Case = CaseBuilder.getCase();
2539 SI->addCase(Case, DestBB);
2545 for (SmallVector::iterator cvi = CaseVals.begin(),
2546 cve = CaseVals.end(); cvi != cve; ++cvi)
2547 SI->addCase(*cvi, DestBB);
25402548 }
2541 uint16_t Hash = SI->hash();
2542 if (Hash != (Record[0] & 0xFFFF))
2543 return Error("Invalid SWITCH record");
25442549 I = SI;
25452550 break;
25462551 }
5959 FUNCTION_INST_CAST_ABBREV,
6060 FUNCTION_INST_RET_VOID_ABBREV,
6161 FUNCTION_INST_RET_VAL_ABBREV,
62 FUNCTION_INST_UNREACHABLE_ABBREV,
63
64 // SwitchInst Magic
65 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
62 FUNCTION_INST_UNREACHABLE_ABBREV
6663 };
6764
6865 static unsigned GetEncodedCastOpcode(unsigned Opcode) {
864861 Vals.push_back((-V << 1) | 1);
865862 }
866863
867 static void EmitAPInt(SmallVectorImpl &Vals,
868 unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
869 bool EmitSizeForWideNumbers = false
870 ) {
871 if (Val.getBitWidth() <= 64) {
872 uint64_t V = Val.getSExtValue();
873 emitSignedInt64(Vals, V);
874 Code = bitc::CST_CODE_INTEGER;
875 AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
876 } else {
877 // Wide integers, > 64 bits in size.
878 // We have an arbitrary precision integer value to write whose
879 // bit width is > 64. However, in canonical unsigned integer
880 // format it is likely that the high bits are going to be zero.
881 // So, we only write the number of active words.
882 unsigned NWords = Val.getActiveWords();
883
884 if (EmitSizeForWideNumbers)
885 Vals.push_back(NWords);
886
887 const uint64_t *RawWords = Val.getRawData();
888 for (unsigned i = 0; i != NWords; ++i) {
889 emitSignedInt64(Vals, RawWords[i]);
890 }
891 Code = bitc::CST_CODE_WIDE_INTEGER;
892 }
893 }
894
895864 static void WriteConstants(unsigned FirstVal, unsigned LastVal,
896865 const ValueEnumerator &VE,
897866 BitstreamWriter &Stream, bool isGlobal) {
975944 } else if (isa(C)) {
976945 Code = bitc::CST_CODE_UNDEF;
977946 } else if (const ConstantInt *IV = dyn_cast(C)) {
978 EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
947 if (IV->getBitWidth() <= 64) {
948 uint64_t V = IV->getSExtValue();
949 emitSignedInt64(Record, V);
950 Code = bitc::CST_CODE_INTEGER;
951 AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
952 } else { // Wide integers, > 64 bits in size.
953 // We have an arbitrary precision integer value to write whose
954 // bit width is > 64. However, in canonical unsigned integer
955 // format it is likely that the high bits are going to be zero.
956 // So, we only write the number of active words.
957 unsigned NWords = IV->getValue().getActiveWords();
958 const uint64_t *RawWords = IV->getValue().getRawData();
959 for (unsigned i = 0; i != NWords; ++i) {
960 emitSignedInt64(Record, RawWords[i]);
961 }
962 Code = bitc::CST_CODE_WIDE_INTEGER;
963 }
979964 } else if (const ConstantFP *CFP = dyn_cast(C)) {
980965 Code = bitc::CST_CODE_FLOAT;
981966 Type *Ty = CFP->getType();
11831168 Vals.push_back(InstID - ValID);
11841169 }
11851170
1186 static void pushValue64(const Value *V, unsigned InstID,
1187 SmallVectorImpl &Vals,
1188 ValueEnumerator &VE) {
1189 uint64_t ValID = VE.getValueID(V);
1190 Vals.push_back(InstID - ValID);
1191 }
1192
11931171 static void pushValueSigned(const Value *V, unsigned InstID,
11941172 SmallVectorImpl &Vals,
11951173 ValueEnumerator &VE) {
13131291 break;
13141292 case Instruction::Switch:
13151293 {
1316 // Redefine Vals, since here we need to use 64 bit values
1317 // explicitly to store large APInt numbers.
1318 SmallVector Vals64;
1319
13201294 Code = bitc::FUNC_CODE_INST_SWITCH;
13211295 const SwitchInst &SI = cast(I);
1322
1323 uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
1324 Vals64.push_back(SwitchRecordHeader);
1325
1326 Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
1327 pushValue64(SI.getCondition(), InstID, Vals64, VE);
1328 Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
1329 Vals64.push_back(SI.getNumCases());
1296 Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
1297 pushValue(SI.getCondition(), InstID, Vals, VE);
1298 Vals.push_back(VE.getValueID(SI.getDefaultDest()));
13301299 for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
13311300 i != e; ++i) {
1332 const IntegersSubset& CaseRanges = i.getCaseValueEx();
1333 unsigned Code, Abbrev; // will unused.
1334
1335 if (CaseRanges.isSingleNumber()) {
1336 Vals64.push_back(1/*NumItems = 1*/);
1337 Vals64.push_back(true/*IsSingleNumber = true*/);
1338 EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
1339 } else {
1340
1341 Vals64.push_back(CaseRanges.getNumItems());
1342
1343 if (CaseRanges.isSingleNumbersOnly()) {
1344 for (unsigned ri = 0, rn = CaseRanges.getNumItems();
1345 ri != rn; ++ri) {
1346
1347 Vals64.push_back(true/*IsSingleNumber = true*/);
1348
1349 EmitAPInt(Vals64, Code, Abbrev,
1350 CaseRanges.getSingleNumber(ri), true);
1351 }
1352 } else
1353 for (unsigned ri = 0, rn = CaseRanges.getNumItems();
1354 ri != rn; ++ri) {
1355 IntegersSubset::Range r = CaseRanges.getItem(ri);
1356 bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
1357
1358 Vals64.push_back(IsSingleNumber);
1359
1360 EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
1361 if (!IsSingleNumber)
1362 EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
1363 }
1364 }
1365 Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
1366 }
1367
1368 Stream.EmitRecord(Code, Vals64, AbbrevToUse);
1369
1370 // Also do expected action - clear external Vals collection:
1371 Vals.clear();
1372 return;
1301 Vals.push_back(VE.getValueID(i.getCaseValue()));
1302 Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
1303 }
13731304 }
13741305 break;
13751306 case Instruction::IndirectBr:
4848 #include "llvm/Support/CommandLine.h"
4949 #include "llvm/Support/Debug.h"
5050 #include "llvm/Support/ErrorHandling.h"
51 #include "llvm/Support/IntegersSubsetMapping.h"
5251 #include "llvm/Support/MathExtras.h"
5352 #include "llvm/Support/raw_ostream.h"
5453 #include "llvm/Target/TargetFrameLowering.h"
16171616 } else
16181617 Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
16191618 } else {
1620 assert(CB.CC == ISD::SETCC_INVALID &&
1621 "Condition is undefined for to-the-range belonging check.");
1619 assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now");
16221620
16231621 const APInt& Low = cast(CB.CmpLHS)->getValue();
16241622 const APInt& High = cast(CB.CmpRHS)->getValue();
16261624 SDValue CmpOp = getValue(CB.CmpMHS);
16271625 EVT VT = CmpOp.getValueType();
16281626
1629 if (cast(CB.CmpLHS)->isMinValue(false)) {
1627 if (cast(CB.CmpLHS)->isMinValue(true)) {
16301628 Cond = DAG.getSetCC(dl, MVT::i1, CmpOp, DAG.getConstant(High, VT),
1631 ISD::SETULE);
1629 ISD::SETLE);
16321630 } else {
16331631 SDValue SUB = DAG.getNode(ISD::SUB, dl,
16341632 VT, CmpOp, DAG.getConstant(Low, VT));
21442142 CC = ISD::SETEQ;
21452143 LHS = SV; RHS = I->High; MHS = NULL;
21462144 } else {
2147 CC = ISD::SETCC_INVALID;
2145 CC = ISD::SETLE;
21482146 LHS = I->Low; MHS = SV; RHS = I->High;
21492147 }
21502148
21782176
21792177 static APInt ComputeRange(const APInt &First, const APInt &Last) {
21802178 uint32_t BitWidth = std::max(Last.getBitWidth(), First.getBitWidth()) + 1;
2181 APInt LastExt = Last.zext(BitWidth), FirstExt = First.zext(BitWidth);
2179 APInt LastExt = Last.sext(BitWidth), FirstExt = First.sext(BitWidth);
21822180 return (LastExt - FirstExt + 1ULL);
21832181 }
21842182
22452243 const APInt &Low = cast(I->Low)->getValue();
22462244 const APInt &High = cast(I->High)->getValue();
22472245
2248 if (Low.ule(TEI) && TEI.ule(High)) {
2246 if (Low.sle(TEI) && TEI.sle(High)) {
22492247 DestBBs.push_back(I->BB);
22502248 if (TEI==High)
22512249 ++I;
24192417 // Create a CaseBlock record representing a conditional branch to
24202418 // the LHS node if the value being switched on SV is less than C.
24212419 // Otherwise, branch to LHS.
2422 CaseBlock CB(ISD::SETULT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB);
2420 CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB);
24232421
24242422 if (CR.CaseBB == SwitchBB)
24252423 visitSwitchCase(CB, SwitchBB);
24922490 // Optimize the case where all the case values fit in a
24932491 // word without having to subtract minValue. In this case,
24942492 // we can optimize away the subtraction.
2495 if (maxValue.ult(IntPtrBits)) {
2493 if (minValue.isNonNegative() && maxValue.slt(IntPtrBits)) {
24962494 cmpRange = maxValue;
24972495 } else {
24982496 lowBound = minValue;
25672565 /// Clusterify - Transform simple list of Cases into list of CaseRange's
25682566 size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
25692567 const SwitchInst& SI) {
2570
2571 /// Use a shorter form of declaration, and also
2572 /// show the we want to use CRSBuilder as Clusterifier.
2573 typedef IntegersSubsetMapping Clusterifier;
2574
2575 Clusterifier TheClusterifier;
2568 size_t numCmps = 0;
25762569
25772570 BranchProbabilityInfo *BPI = FuncInfo.BPI;
25782571 // Start with "simple" cases
25812574 const BasicBlock *SuccBB = i.getCaseSuccessor();
25822575 MachineBasicBlock *SMBB = FuncInfo.MBBMap[SuccBB];
25832576
2584 TheClusterifier.add(i.getCaseValueEx(), SMBB,
2585 BPI ? BPI->getEdgeWeight(SI.getParent(), i.getSuccessorIndex()) : 0);
2586 }
2587
2588 TheClusterifier.optimize();
2589
2590 size_t numCmps = 0;
2591 for (Clusterifier::RangeIterator i = TheClusterifier.begin(),
2592 e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
2593 Clusterifier::Cluster &C = *i;
2594 // Update edge weight for the cluster.
2595 unsigned W = C.first.Weight;
2596
2597 // FIXME: Currently work with ConstantInt based numbers.
2598 // Changing it to APInt based is a pretty heavy for this commit.
2599 Cases.push_back(Case(C.first.getLow().toConstantInt(),
2600 C.first.getHigh().toConstantInt(), C.second, W));
2601
2602 if (C.first.getLow() != C.first.getHigh())
2603 // A range counts double, since it requires two compares.
2604 ++numCmps;
2577 uint32_t ExtraWeight =
2578 BPI ? BPI->getEdgeWeight(SI.getParent(), i.getSuccessorIndex()) : 0;
2579
2580 Cases.push_back(Case(i.getCaseValue(), i.getCaseValue(),
2581 SMBB, ExtraWeight));
2582 }
2583 std::sort(Cases.begin(), Cases.end(), CaseCmp());
2584
2585 // Merge case into clusters
2586 if (Cases.size() >= 2)
2587 // Must recompute end() each iteration because it may be
2588 // invalidated by erase if we hold on to it
2589 for (CaseItr I = Cases.begin(), J = llvm::next(Cases.begin());
2590 J != Cases.end(); ) {
2591 const APInt& nextValue = cast(J->Low)->getValue();
2592 const APInt& currentValue = cast(I->High)->getValue();
2593 MachineBasicBlock* nextBB = J->BB;
2594 MachineBasicBlock* currentBB = I->BB;
2595
2596 // If the two neighboring cases go to the same destination, merge them
2597 // into a single case.
2598 if ((nextValue - currentValue == 1) && (currentBB == nextBB)) {
2599 I->High = J->High;
2600 I->ExtraWeight += J->ExtraWeight;
2601 J = Cases.erase(J);
2602 } else {
2603 I = J++;
2604 }
2605 }
2606
2607 for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) {
2608 if (I->Low != I->High)
2609 // A range counts double, since it requires two compares.
2610 ++numCmps;
26052611 }
26062612
26072613 return numCmps;
181181
182182 typedef std::vector CaseRecVector;
183183
184 /// The comparison function for sorting the switch case values in the vector.
185 /// WARNING: Case ranges should be disjoint!
186 struct CaseCmp {
187 bool operator()(const Case &C1, const Case &C2) {
188 assert(isa(C1.Low) && isa(C2.High));
189 const ConstantInt* CI1 = cast(C1.Low);
190 const ConstantInt* CI2 = cast(C2.High);
191 return CI1->getValue().slt(CI2->getValue());
192 }
193 };
194
184195 struct CaseBitsCmp {
185196 bool operator()(const CaseBits &C1, const CaseBits &C2) {
186197 return C1.Bits > C2.Bits;
897897 // Check to see if any of the cases match...
898898 BasicBlock *Dest = 0;
899899 for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
900 IntegersSubset& Case = i.getCaseValueEx();
901 if (Case.isSingleNumber()) {
902 // FIXME: Currently work with ConstantInt based numbers.
903 const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt();
904 GenericValue Val = getOperandValue(const_cast(CI), SF);
905 if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
906 Dest = cast(i.getCaseSuccessor());
907 break;
908 }
909 }
910 if (Case.isSingleNumbersOnly()) {
911 for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
912 // FIXME: Currently work with ConstantInt based numbers.
913 const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt();
914 GenericValue Val = getOperandValue(const_cast(CI), SF);
915 if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
916 Dest = cast(i.getCaseSuccessor());
917 break;
918 }
919 }
920 } else
921 for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
922 IntegersSubset::Range r = Case.getItem(n);
923 // FIXME: Currently work with ConstantInt based numbers.
924 const ConstantInt *LowCI = r.getLow().toConstantInt();
925 const ConstantInt *HighCI = r.getHigh().toConstantInt();
926 GenericValue Low = getOperandValue(const_cast(LowCI), SF);
927 GenericValue High = getOperandValue(const_cast(HighCI), SF);
928 if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
929 executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
930 Dest = cast(i.getCaseSuccessor());
931 break;
932 }
933 }
900 GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF);
901 if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
902 Dest = cast(i.getCaseSuccessor());
903 break;
904 }
934905 }
935906 if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
936907 SwitchToNewBasicBlock(Dest, SF);
32663266 OL[i] = InOL[i];
32673267 OL[i+1] = InOL[i+1];
32683268 }
3269 TheSubsets = SI.TheSubsets;
32703269 SubclassOptionalData = SI.SubclassOptionalData;
32713270 }
32723271
32783277 /// addCase - Add an entry to the switch instruction...
32793278 ///
32803279 void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
3281 IntegersSubsetToBB Mapping;
3282
3283 // FIXME: Currently we work with ConstantInt based cases.
3284 // So inititalize IntItem container directly from ConstantInt.
3285 Mapping.add(IntItem::fromConstantInt(OnVal));
3286 IntegersSubset CaseRanges = Mapping.getCase();
3287 addCase(CaseRanges, Dest);
3288 }
3289
3290 void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) {
32913280 unsigned NewCaseIdx = getNumCases();
32923281 unsigned OpNo = NumOperands;
32933282 if (OpNo+2 > ReservedSpace)
32953284 // Initialize some new operands.
32963285 assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
32973286 NumOperands = OpNo+2;
3298
3299 SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal);
3300
3301 CaseIt Case(this, NewCaseIdx, TheSubsetsIt);
3302 Case.updateCaseValueOperand(OnVal);
3287 CaseIt Case(this, NewCaseIdx);
3288 Case.setValue(OnVal);
33033289 Case.setSuccessor(Dest);
33043290 }
33053291
33063292 /// removeCase - This method removes the specified case and its successor
33073293 /// from the switch instruction.
3308 void SwitchInst::removeCase(CaseIt& i) {
3294 void SwitchInst::removeCase(CaseIt i) {
33093295 unsigned idx = i.getCaseIndex();
33103296
33113297 assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
33223308 // Nuke the last value.
33233309 OL[NumOps-2].set(0);
33243310 OL[NumOps-2+1].set(0);
3325
3326 // Do the same with TheCases collection:
3327 if (i.SubsetIt != --TheSubsets.end()) {
3328 *i.SubsetIt = TheSubsets.back();
3329 TheSubsets.pop_back();
3330 } else {
3331 TheSubsets.pop_back();
3332 i.SubsetIt = TheSubsets.end();
3333 }
3334
33353311 NumOperands = NumOps-2;
33363312 }
33373313
11671167 // Check to make sure that all of the constants in the switch instruction
11681168 // have the same type as the switched-on value.
11691169 Type *SwitchTy = SI.getCondition()->getType();
1170 IntegerType *IntTy = cast(SwitchTy);
1171 IntegersSubsetToBB Mapping;
1172 std::map RangeSetMap;
1170 SmallPtrSet Constants;
11731171 for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
1174 IntegersSubset CaseRanges = i.getCaseValueEx();
1175 for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
1176 IntegersSubset::Range r = CaseRanges.getItem(ri);
1177 Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
1178 "Switch constants must all be same type as switch value!", &SI);
1179 Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
1180 "Switch constants must all be same type as switch value!", &SI);
1181 Mapping.add(r);
1182 RangeSetMap[r] = i.getCaseIndex();
1183 }
1184 }
1185
1186 IntegersSubsetToBB::RangeIterator errItem;
1187 if (!Mapping.verify(errItem)) {
1188 unsigned CaseIndex = RangeSetMap[errItem->first];
1189 SwitchInst::CaseIt i(&SI, CaseIndex);
1190 Assert2(false, "Duplicate integer as switch case", &SI, i.getCaseValueEx());
1172 Assert1(i.getCaseValue()->getType() == SwitchTy,
1173 "Switch constants must all be same type as switch value!", &SI);
1174 Assert2(Constants.insert(i.getCaseValue()),
1175 "Duplicate integer as switch case", &SI, i.getCaseValue());
11911176 }
11921177
11931178 visitTerminatorInst(SI);
11391139 nl(Out);
11401140 for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end();
11411141 i != e; ++i) {
1142 const IntegersSubset CaseVal = i.getCaseValueEx();
1142 const ConstantInt* CaseVal = i.getCaseValue();
11431143 const BasicBlock *BB = i.getCaseSuccessor();
11441144 Out << iName << "->addCase("
11451145 << getOpName(CaseVal) << ", "
2424 #include "llvm/InstVisitor.h"
2525 #include "llvm/IR/DataLayout.h"
2626 #include "llvm/IR/Instruction.h"
27 #include "llvm/IR/LLVMContext.h"
2728 #include "llvm/IR/Module.h"
2829 #include "llvm/Transforms/Instrumentation.h"
2930 #include "llvm/Transforms/Utils/Cloning.h"
664664 TheSwitch->setCondition(call);
665665 TheSwitch->setDefaultDest(TheSwitch->getSuccessor(NumExitBlocks));
666666 // Remove redundant case
667 SwitchInst::CaseIt ToBeRemoved(TheSwitch, NumExitBlocks-1);
668 TheSwitch->removeCase(ToBeRemoved);
667 TheSwitch->removeCase(SwitchInst::CaseIt(TheSwitch, NumExitBlocks-1));
669668 break;
670669 }
671670 }
195195 // Otherwise, we can fold this switch into a conditional branch
196196 // instruction if it has only one non-default destination.
197197 SwitchInst::CaseIt FirstCase = SI->case_begin();
198 IntegersSubset& Case = FirstCase.getCaseValueEx();
199 if (Case.isSingleNumber()) {
200 // FIXME: Currently work with ConstantInt based numbers.
201 Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
202 Case.getSingleNumber(0).toConstantInt(),
203 "cond");
204
205 // Insert the new branch.
206 BranchInst *NewBr = Builder.CreateCondBr(Cond,
207 FirstCase.getCaseSuccessor(),
208 SI->getDefaultDest());
209 MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
210 if (MD && MD->getNumOperands() == 3) {
211 ConstantInt *SICase = dyn_cast(MD->getOperand(2));
212 ConstantInt *SIDef = dyn_cast(MD->getOperand(1));
213 assert(SICase && SIDef);
214 // The TrueWeight should be the weight for the single case of SI.
215 NewBr->setMetadata(LLVMContext::MD_prof,
216 MDBuilder(BB->getContext()).
217 createBranchWeights(SICase->getValue().getZExtValue(),
218 SIDef->getValue().getZExtValue()));
219 }
220
221 // Delete the old switch.
222 SI->eraseFromParent();
223 return true;
224 }
198 Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
199 FirstCase.getCaseValue(), "cond");
200
201 // Insert the new branch.
202 BranchInst *NewBr = Builder.CreateCondBr(Cond,
203 FirstCase.getCaseSuccessor(),
204 SI->getDefaultDest());
205 MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
206 if (MD && MD->getNumOperands() == 3) {
207 ConstantInt *SICase = dyn_cast(MD->getOperand(2));
208 ConstantInt *SIDef = dyn_cast(MD->getOperand(1));
209 assert(SICase && SIDef);
210 // The TrueWeight should be the weight for the single case of SI.
211 NewBr->setMetadata(LLVMContext::MD_prof,
212 MDBuilder(BB->getContext()).
213 createBranchWeights(SICase->getValue().getZExtValue(),
214 SIDef->getValue().getZExtValue()));
215 }
216
217 // Delete the old switch.
218 SI->eraseFromParent();
219 return true;
225220 }
226221 return false;
227222 }
6565 BasicBlock* OrigBlock, BasicBlock* Default);
6666 unsigned Clusterify(CaseVector& Cases, SwitchInst *SI);
6767 };
68
69 /// The comparison function for sorting the switch case values in the vector.
70 /// WARNING: Case ranges should be disjoint!
71 struct CaseCmp {
72 bool operator () (const LowerSwitch::CaseRange& C1,
73 const LowerSwitch::CaseRange& C2) {
74
75 const ConstantInt* CI1 = cast(C1.Low);
76 const ConstantInt* CI2 = cast(C2.High);
77 return CI1->getValue().slt(CI2->getValue());
78 }
79 };
6880 }
6981
7082 char LowerSwitch::ID = 0;
146158 Function::iterator FI = OrigBlock;
147159 F->getBasicBlockList().insert(++FI, NewNode);
148160
149 ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_ULT,
161 ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_SLT,
150162 Val, Pivot.Low, "Pivot");
151163 NewNode->getInstList().push_back(Comp);
152164 BranchInst::Create(LBranch, RBranch, Comp, NewNode);
221233
222234 // Clusterify - Transform simple list of Cases into list of CaseRange's
223235 unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
224
225 IntegersSubsetToBB TheClusterifier;
236 unsigned numCmps = 0;
226237
227238 // Start with "simple" cases
228 for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
229 i != e; ++i) {
230 BasicBlock *SuccBB = i.getCaseSuccessor();
231 IntegersSubset CaseRanges = i.getCaseValueEx();
232 TheClusterifier.add(CaseRanges, SuccBB);
233 }
239 for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i)
240 Cases.push_back(CaseRange(i.getCaseValue(), i.getCaseValue(),
241 i.getCaseSuccessor()));
234242
235 TheClusterifier.optimize();
236
237 size_t numCmps = 0;
238 for (IntegersSubsetToBB::RangeIterator i = TheClusterifier.begin(),
239 e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
240 IntegersSubsetToBB::Cluster &C = *i;
241
242 // FIXME: Currently work with ConstantInt based numbers.
243 // Changing it to APInt based is a pretty heavy for this commit.
244 Cases.push_back(CaseRange(C.first.getLow().toConstantInt(),
245 C.first.getHigh().toConstantInt(), C.second));
246 if (C.first.isSingleNumber())
243 std::sort(Cases.begin(), Cases.end(), CaseCmp());
244
245 // Merge case into clusters
246 if (Cases.size()>=2)
247 for (CaseItr I=Cases.begin(), J=llvm::next(Cases.begin()); J!=Cases.end(); ) {
248 int64_t nextValue = cast(J->Low)->getSExtValue();
249 int64_t currentValue = cast(I->High)->getSExtValue();
250 BasicBlock* nextBB = J->BB;
251 BasicBlock* currentBB = I->BB;
252
253 // If the two neighboring cases go to the same destination, merge them
254 // into a single case.
255 if ((nextValue-currentValue==1) && (currentBB == nextBB)) {
256 I->High = J->High;
257 J = Cases.erase(J);
258 } else {
259 I = J++;
260 }
261 }
262
263 for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) {
264 if (I->Low != I->High)
247265 // A range counts double, since it requires two compares.
248266 ++numCmps;
249267 }
250268
251 return numCmps;
269 return numCmps;
252270 }
253271
254272 // processSwitchInst - Replace the specified switch instruction with a sequence
+0
-33
test/Bitcode/2012-05-07-SwitchInstRangesSupport.ll less more
None ; RUN: rm -f %t.bc
1 ; RUN: rm -f %t.ll
2 ; RUN: rm -f %t2.bc
3 ; RUN: rm -f %t2.ll
4 ; RUN: llvm-as %s -o %t.bc
5 ; RUN: llvm-dis %t.bc -o - | tail -n +2 > %t.ll
6 ; RUN: llvm-as %t.ll -o %t2.bc
7 ; RUN: llvm-dis %t2.bc -o - | tail -n +2 > %t2.ll
8 ; RUN: llvm-diff %t.ll %t2.ll
9
10 define void @test() {
11 %mem = alloca i32
12 store i32 2, i32* %mem
13 %c = load i32* %mem
14 switch i32 %c, label %exit [
15 i32 1, label %exit
16 i32 2, label %exit
17 ]
18 exit:
19 ret void
20 }
21 define void @test_wide() {
22 %mem = alloca i256
23 store i256 2, i256* %mem
24 %c = load i256* %mem
25 switch i256 %c, label %exit [
26 i256 123456789012345678901234567890, label %exit
27 i256 2, label %exit
28 ]
29 exit:
30 ret void
31 }
32
0 ; RUN: llvm-dis < %s.bc| FileCheck %s
1
2 ; case-ranges.ll.bc was generated by passing this file to llvm-as from the 3.3
3 ; release of LLVM. This tests that the bitcode for switches from that release
4 ; can still be read.
5
6 define i32 @foo(i32 %x) nounwind ssp uwtable {
7 ; CHECK: define i32 @foo
8 %1 = alloca i32, align 4
9 %2 = alloca i32, align 4
10 store i32 %x, i32* %2, align 4
11 %3 = load i32* %2, align 4
12 switch i32 %3, label %9 [
13 ; CHECK: switch i32 %3, label %9
14 i32 -3, label %4
15 ; CHECK-NEXT: i32 -3, label %4
16 i32 -2, label %4
17 ; CHECK-NEXT: i32 -2, label %4
18 i32 -1, label %4
19 ; CHECK-NEXT: i32 -1, label %4
20 i32 0, label %4
21 ; CHECK-NEXT: i32 0, label %4
22 i32 1, label %4
23 ; CHECK-NEXT: i32 1, label %4
24 i32 2, label %4
25 ; CHECK-NEXT: i32 2, label %4
26 i32 4, label %5
27 ; CHECK-NEXT: i32 4, label %5
28 i32 5, label %6
29 ; CHECK-NEXT: i32 5, label %6
30 i32 6, label %7
31 ; CHECK-NEXT: i32 6, label %7
32 i32 7, label %8
33 ; CHECK-NEXT: i32 7, label %8
34 ]
35
36 ;
37 store i32 -1, i32* %1
38 br label %11
39
40 ;
41 store i32 2, i32* %1
42 br label %11
43
44 ;
45 store i32 1, i32* %1
46 br label %11
47
48 ;
49 store i32 4, i32* %1
50 br label %11
51
52 ;
53 store i32 3, i32* %1
54 br label %11
55
56 ;
57 br label %10
58
59 ;
60 store i32 0, i32* %1
61 br label %11
62
63 ;
64 %12 = load i32* %1
65 ret i32 %12
66 }
66 ;CHECK-NEXT: br label %NodeBlock37
77
88 ;CHECK: NodeBlock37: ; preds = %entry
9 ;CHECK-NEXT: %Pivot38 = icmp ult i32 %tmp158, 11
9 ;CHECK-NEXT: %Pivot38 = icmp slt i32 %tmp158, 10
1010 ;CHECK-NEXT: br i1 %Pivot38, label %NodeBlock13, label %NodeBlock35
1111
1212 ;CHECK: NodeBlock35: ; preds = %NodeBlock37
13 ;CHECK-NEXT: %Pivot36 = icmp ult i32 %tmp158, 14
13 ;CHECK-NEXT: %Pivot36 = icmp slt i32 %tmp158, 13
1414 ;CHECK-NEXT: br i1 %Pivot36, label %NodeBlock23, label %NodeBlock33
1515
1616 ;CHECK: NodeBlock33: ; preds = %NodeBlock35
17 ;CHECK-NEXT: %Pivot34 = icmp ult i32 %tmp158, 15
17 ;CHECK-NEXT: %Pivot34 = icmp slt i32 %tmp158, 14
1818 ;CHECK-NEXT: br i1 %Pivot34, label %LeafBlock25, label %NodeBlock31
1919
2020 ;CHECK: NodeBlock31: ; preds = %NodeBlock33
21 ;CHECK-NEXT: %Pivot32 = icmp ult i32 %tmp158, -6
21 ;CHECK-NEXT: %Pivot32 = icmp slt i32 %tmp158, 15
2222 ;CHECK-NEXT: br i1 %Pivot32, label %LeafBlock27, label %LeafBlock29
2323
2424 ;CHECK: LeafBlock29: ; preds = %NodeBlock31
25 ;CHECK-NEXT: %tmp158.off = add i32 %tmp158, 6
26 ;CHECK-NEXT: %SwitchLeaf30 = icmp ule i32 %tmp158.off, 4
27 ;CHECK-NEXT: br i1 %SwitchLeaf30, label %bb338, label %NewDefault
25 ;CHECK-NEXT: %SwitchLeaf30 = icmp eq i32 %tmp158, 15
26 ;CHECK-NEXT: br i1 %SwitchLeaf30, label %bb334, label %NewDefault
2827
2928 ;CHECK: LeafBlock27: ; preds = %NodeBlock31
30 ;CHECK-NEXT: %SwitchLeaf28 = icmp eq i32 %tmp158, 15
31 ;CHECK-NEXT: br i1 %SwitchLeaf28, label %bb334, label %NewDefault
29 ;CHECK-NEXT: %SwitchLeaf28 = icmp eq i32 %tmp158, 14
30 ;CHECK-NEXT: br i1 %SwitchLeaf28, label %bb332, label %NewDefault
3231
3332 ;CHECK: LeafBlock25: ; preds = %NodeBlock33
34 ;CHECK-NEXT: %SwitchLeaf26 = icmp eq i32 %tmp158, 14
35 ;CHECK-NEXT: br i1 %SwitchLeaf26, label %bb332, label %NewDefault
33 ;CHECK-NEXT: %SwitchLeaf26 = icmp eq i32 %tmp158, 13
34 ;CHECK-NEXT: br i1 %SwitchLeaf26, label %bb330, label %NewDefault
3635
3736 ;CHECK: NodeBlock23: ; preds = %NodeBlock35
38 ;CHECK-NEXT: %Pivot24 = icmp ult i32 %tmp158, 12
37 ;CHECK-NEXT: %Pivot24 = icmp slt i32 %tmp158, 11
3938 ;CHECK-NEXT: br i1 %Pivot24, label %LeafBlock15, label %NodeBlock21
4039
4140 ;CHECK: NodeBlock21: ; preds = %NodeBlock23
42 ;CHECK-NEXT: %Pivot22 = icmp ult i32 %tmp158, 13
41 ;CHECK-NEXT: %Pivot22 = icmp slt i32 %tmp158, 12
4342 ;CHECK-NEXT: br i1 %Pivot22, label %LeafBlock17, label %LeafBlock19
4443
4544 ;CHECK: LeafBlock19: ; preds = %NodeBlock21
46 ;CHECK-NEXT: %SwitchLeaf20 = icmp eq i32 %tmp158, 13
47 ;CHECK-NEXT: br i1 %SwitchLeaf20, label %bb330, label %NewDefault
45 ;CHECK-NEXT: %SwitchLeaf20 = icmp eq i32 %tmp158, 12
46 ;CHECK-NEXT: br i1 %SwitchLeaf20, label %bb328, label %NewDefault
4847
4948 ;CHECK: LeafBlock17: ; preds = %NodeBlock21
50 ;CHECK-NEXT: %SwitchLeaf18 = icmp eq i32 %tmp158, 12
51 ;CHECK-NEXT: br i1 %SwitchLeaf18, label %bb328, label %NewDefault
49 ;CHECK-NEXT: %SwitchLeaf18 = icmp eq i32 %tmp158, 11
50 ;CHECK-NEXT: br i1 %SwitchLeaf18, label %bb326, label %NewDefault
5251
5352 ;CHECK: LeafBlock15: ; preds = %NodeBlock23
54 ;CHECK-NEXT: %SwitchLeaf16 = icmp eq i32 %tmp158, 11
55 ;CHECK-NEXT: br i1 %SwitchLeaf16, label %bb326, label %NewDefault
53 ;CHECK-NEXT: %SwitchLeaf16 = icmp eq i32 %tmp158, 10
54 ;CHECK-NEXT: br i1 %SwitchLeaf16, label %bb324, label %NewDefault
5655
5756 ;CHECK: NodeBlock13: ; preds = %NodeBlock37
58 ;CHECK-NEXT: %Pivot14 = icmp ult i32 %tmp158, 8
57 ;CHECK-NEXT: %Pivot14 = icmp slt i32 %tmp158, 7
5958 ;CHECK-NEXT: br i1 %Pivot14, label %NodeBlock, label %NodeBlock11
6059
6160 ;CHECK: NodeBlock11: ; preds = %NodeBlock13
62 ;CHECK-NEXT: %Pivot12 = icmp ult i32 %tmp158, 9
61 ;CHECK-NEXT: %Pivot12 = icmp slt i32 %tmp158, 8
6362 ;CHECK-NEXT: br i1 %Pivot12, label %LeafBlock3, label %NodeBlock9
6463
6564 ;CHECK: NodeBlock9: ; preds = %NodeBlock11
66 ;CHECK-NEXT: %Pivot10 = icmp ult i32 %tmp158, 10
65 ;CHECK-NEXT: %Pivot10 = icmp slt i32 %tmp158, 9
6766 ;CHECK-NEXT: br i1 %Pivot10, label %LeafBlock5, label %LeafBlock7
6867
6968 ;CHECK: LeafBlock7: ; preds = %NodeBlock9
70 ;CHECK-NEXT: %SwitchLeaf8 = icmp eq i32 %tmp158, 10
71 ;CHECK-NEXT: br i1 %SwitchLeaf8, label %bb324, label %NewDefault
69 ;CHECK-NEXT: %SwitchLeaf8 = icmp eq i32 %tmp158, 9
70 ;CHECK-NEXT: br i1 %SwitchLeaf8, label %bb322, label %NewDefault
7271
7372 ;CHECK: LeafBlock5: ; preds = %NodeBlock9
74 ;CHECK-NEXT: %SwitchLeaf6 = icmp eq i32 %tmp158, 9
75 ;CHECK-NEXT: br i1 %SwitchLeaf6, label %bb322, label %NewDefault
73 ;CHECK-NEXT: %SwitchLeaf6 = icmp eq i32 %tmp158, 8
74 ;CHECK-NEXT: br i1 %SwitchLeaf6, label %bb338, label %NewDefault
7675
7776 ;CHECK: LeafBlock3: ; preds = %NodeBlock11
78 ;CHECK-NEXT: %SwitchLeaf4 = icmp eq i32 %tmp158, 8
79 ;CHECK-NEXT: br i1 %SwitchLeaf4, label %bb338, label %NewDefault
77 ;CHECK-NEXT: %SwitchLeaf4 = icmp eq i32 %tmp158, 7
78 ;CHECK-NEXT: br i1 %SwitchLeaf4, label %bb, label %NewDefault
8079
8180 ;CHECK: NodeBlock: ; preds = %NodeBlock13
82 ;CHECK-NEXT: %Pivot = icmp ult i32 %tmp158, 7
81 ;CHECK-NEXT: %Pivot = icmp slt i32 %tmp158, 0
8382 ;CHECK-NEXT: br i1 %Pivot, label %LeafBlock, label %LeafBlock1
8483
8584 ;CHECK: LeafBlock1: ; preds = %NodeBlock
86 ;CHECK-NEXT: %SwitchLeaf2 = icmp eq i32 %tmp158, 7
87 ;CHECK-NEXT: br i1 %SwitchLeaf2, label %bb, label %NewDefault
85 ;CHECK-NEXT: %SwitchLeaf2 = icmp ule i32 %tmp158, 6
86 ;CHECK-NEXT: br i1 %SwitchLeaf2, label %bb338, label %NewDefault
8887
8988 ;CHECK: LeafBlock: ; preds = %NodeBlock
90 ;CHECK-NEXT: %SwitchLeaf = icmp ule i32 %tmp158, 6
89 ;CHECK-NEXT: %tmp158.off = add i32 %tmp158, 6
90 ;CHECK-NEXT: %SwitchLeaf = icmp ule i32 %tmp158.off, 4
9191 ;CHECK-NEXT: br i1 %SwitchLeaf, label %bb338, label %NewDefault
9292
9393 define i32 @main(i32 %tmp158) {
315315
316316 bool Difference = false;
317317
318 DenseMap*, BasicBlock*> LCases;
318 DenseMapInt*,BasicBlock*> LCases;
319319
320320 for (SwitchInst::CaseIt I = LI->case_begin(), E = LI->case_end();
321321 I != E; ++I)
322 LCases[I.getCaseValueEx()] = I.getCaseSuccessor();
322 LCases[I.getCaseValue()] = I.getCaseSuccessor();
323323
324324 for (SwitchInst::CaseIt I = RI->case_begin(), E = RI->case_end();
325325 I != E; ++I) {
326 IntegersSubset CaseValue = I.getCaseValueEx();
326 ConstantInt *CaseValue = I.getCaseValue();
327327 BasicBlock *LCase = LCases[CaseValue];
328328 if (LCase) {
329329 if (TryUnify) tryUnify(LCase, I.getCaseSuccessor());
335335 }
336336 }
337337 if (!Difference)
338 for (DenseMap*, BasicBlock*>::iterator
338 for (DenseMapInt*,BasicBlock*>::iterator
339339 I = LCases.begin(), E = LCases.end(); I != E; ++I) {
340340 if (Complain)
341341 Engine.logf("left switch has extra case %l") << I->first;
88
99 // we perform white-box tests
1010 //
11 #include "llvm/IR/Constants.h"
1112 #include "llvm/IR/Function.h"
1213 #include "llvm/IR/Instructions.h"
1314 #include "llvm/IR/LLVMContext.h"
+0
-326
unittests/Support/IntegersSubsetTest.cpp less more
None //===- llvm/unittest/Support/IntegersSubsetTest.cpp - IntegersSubset tests ===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/IntegersSubset.h"
10 #include "llvm/ADT/APInt.h"
11 #include "llvm/Support/IntegersSubsetMapping.h"
12 #include "gtest/gtest.h"
13 #include
14
15 using namespace llvm;
16
17 namespace {
18
19 class Int : public APInt {
20 public:
21 Int() {}
22 Int(uint64_t V) : APInt(64, V) {}
23 Int(const APInt& Src) : APInt(Src) {}
24 bool operator < (const APInt& RHS) const { return ult(RHS); }
25 bool operator > (const APInt& RHS) const { return ugt(RHS); }
26 bool operator <= (const APInt& RHS) const { return ule(RHS); }
27 bool operator >= (const APInt& RHS) const { return uge(RHS); }
28 };
29
30 typedef IntRange Range;
31 typedef IntegersSubsetGeneric Subset;
32 typedef IntegersSubsetMapping Mapping;
33
34 TEST(IntegersSubsetTest, GeneralTest) {
35
36 // Test construction.
37
38 std::vector Ranges;
39 Ranges.reserve(3);
40
41 // Initialize Subset as union of three pairs:
42 // { {0, 8}, {10, 18}, {20, 28} }
43 for (unsigned i = 0; i < 3; ++i)
44 Ranges.push_back(Range(Int(i*10), Int(i*10 + 8)));
45
46 Subset TheSubset(Ranges);
47
48 for (unsigned i = 0; i < 3; ++i) {
49 EXPECT_EQ(TheSubset.getItem(i).getLow(), Int(i*10));
50 EXPECT_EQ(TheSubset.getItem(i).getHigh(), Int(i*10 + 8));
51 }
52
53 EXPECT_EQ(TheSubset.getNumItems(), 3ULL);
54
55 // Test belonging to range.
56
57 EXPECT_TRUE(TheSubset.isSatisfies(Int(5)));
58 EXPECT_FALSE(TheSubset.isSatisfies(Int(9)));
59
60 // Test when subset contains the only item.
61
62 Ranges.clear();
63 Ranges.push_back(Range(Int(10), Int(10)));
64
65 Subset TheSingleNumber(Ranges);
66
67 EXPECT_TRUE(TheSingleNumber.isSingleNumber());
68
69 Ranges.push_back(Range(Int(12), Int(15)));
70
71 Subset NotASingleNumber(Ranges);
72
73 EXPECT_FALSE(NotASingleNumber.isSingleNumber());
74
75 // Test when subset contains items that are not a ranges but
76 // the single numbers.
77
78 Ranges.clear();
79 Ranges.push_back(Range(Int(10), Int(10)));
80 Ranges.push_back(Range(Int(15), Int(19)));
81
82 Subset WithSingleNumberItems(Ranges);
83
84 EXPECT_TRUE(WithSingleNumberItems.isSingleNumber(0));
85 EXPECT_FALSE(WithSingleNumberItems.isSingleNumber(1));
86
87 // Test size of subset. Note subset itself may be not optimized (improper),
88 // so it may contain duplicates, and the size of subset { {0, 9} {5, 9} }
89 // will 15 instead of 10.
90
91 Ranges.clear();
92 Ranges.push_back(Range(Int(0), Int(9)));
93 Ranges.push_back(Range(Int(5), Int(9)));
94
95 Subset NotOptimizedSubset(Ranges);
96
97 EXPECT_EQ(NotOptimizedSubset.getSize(), 15ULL);
98
99 // Test access to a single value.
100 // getSingleValue(idx) method represents subset as flat numbers collection,
101 // so subset { {0, 3}, {8, 10} } will represented as array
102 // { 0, 1, 2, 3, 8, 9, 10 }.
103
104 Ranges.clear();
105 Ranges.push_back(Range(Int(0), Int(3)));
106 Ranges.push_back(Range(Int(8), Int(10)));
107
108 Subset OneMoreSubset(Ranges);
109
110 EXPECT_EQ(OneMoreSubset.getSingleValue(5), Int(9));
111 }
112
113 TEST(IntegersSubsetTest, MappingTest) {
114
115 Mapping::Cases TheCases;
116
117 unsigned Successors[3] = {0, 1, 2};
118
119 // Test construction.
120
121 Mapping TheMapping;
122 for (unsigned i = 0; i < 3; ++i)
123 TheMapping.add(Int(10*i), Int(10*i + 9), Successors + i);
124 TheMapping.add(Int(111), Int(222), Successors);
125 TheMapping.removeItem(--TheMapping.end());
126
127 TheMapping.getCases(TheCases);
128
129 EXPECT_EQ(TheCases.size(), 3ULL);
130
131 for (unsigned i = 0; i < 3; ++i) {
132 Mapping::Cases::iterator CaseIt = TheCases.begin();
133 std::advance(CaseIt, i);
134 EXPECT_EQ(CaseIt->first, Successors + i);
135 EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL);
136 EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(10*i), Int(10*i + 9)));
137 }
138
139 // Test verification.
140
141 Mapping ImproperMapping;
142 ImproperMapping.add(Int(10), Int(11), Successors + 0);
143 ImproperMapping.add(Int(11), Int(12), Successors + 1);
144
145 Mapping::RangeIterator ErrItem;
146 EXPECT_FALSE(ImproperMapping.verify(ErrItem));
147 EXPECT_EQ(ErrItem, --ImproperMapping.end());
148
149 Mapping ProperMapping;
150 ProperMapping.add(Int(10), Int(11), Successors + 0);
151 ProperMapping.add(Int(12), Int(13), Successors + 1);
152
153 EXPECT_TRUE(ProperMapping.verify(ErrItem));
154
155 // Test optimization.
156
157 Mapping ToBeOptimized;
158
159 for (unsigned i = 0; i < 3; ++i) {
160 ToBeOptimized.add(Int(i * 10), Int(i * 10 + 1), Successors + i);
161 ToBeOptimized.add(Int(i * 10 + 2), Int(i * 10 + 9), Successors + i);
162 }
163
164 ToBeOptimized.optimize();
165
166 TheCases.clear();
167 ToBeOptimized.getCases(TheCases);
168
169 EXPECT_EQ(TheCases.size(), 3ULL);
170
171 for (unsigned i = 0; i < 3; ++i) {
172 Mapping::Cases::iterator CaseIt = TheCases.begin();
173 std::advance(CaseIt, i);
174 EXPECT_EQ(CaseIt->first, Successors + i);
175 EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL);
176 EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(i * 10), Int(i * 10 + 9)));
177 }
178 }
179
180 typedef unsigned unsigned_pair[2];
181 typedef unsigned_pair unsigned_ranges[];
182
183 void TestDiff(
184 const unsigned_ranges LHS,
185 unsigned LSize,
186 const unsigned_ranges RHS,
187 unsigned RSize,
188 const unsigned_ranges ExcludeRes,
189 unsigned ExcludeResSize,
190 const unsigned_ranges IntersectRes,
191 unsigned IntersectResSize
192 ) {
193
194 Mapping::RangesCollection Ranges;
195
196 Mapping LHSMapping;
197 for (unsigned i = 0; i < LSize; ++i)
198 Ranges.push_back(Range(Int(LHS[i][0]), Int(LHS[i][1])));
199 LHSMapping.add(Ranges);
200
201 Ranges.clear();
202
203 Mapping RHSMapping;
204 for (unsigned i = 0; i < RSize; ++i)
205 Ranges.push_back(Range(Int(RHS[i][0]), Int(RHS[i][1])));
206 RHSMapping.add(Ranges);
207
208 Mapping LExclude, Intersection;
209
210 LHSMapping.diff(&LExclude, &Intersection, 0, RHSMapping);
211
212 if (ExcludeResSize) {
213 EXPECT_EQ(LExclude.size(), ExcludeResSize);
214
215 unsigned i = 0;
216 for (Mapping::RangeIterator rei = LExclude.begin(),
217 e = LExclude.end(); rei != e; ++rei, ++i)
218 EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
219 } else
220 EXPECT_TRUE(LExclude.empty());
221
222 if (IntersectResSize) {
223 EXPECT_EQ(Intersection.size(), IntersectResSize);
224
225 unsigned i = 0;
226 for (Mapping::RangeIterator ii = Intersection.begin(),
227 e = Intersection.end(); ii != e; ++ii, ++i)
228 EXPECT_EQ(ii->first, Range(IntersectRes[i][0], IntersectRes[i][1]));
229 } else
230 EXPECT_TRUE(Intersection.empty());
231
232 LExclude.clear();
233 Intersection.clear();
234 RHSMapping.diff(0, &Intersection, &LExclude, LHSMapping);
235
236 // Check LExclude again.
237 if (ExcludeResSize) {
238 EXPECT_EQ(LExclude.size(), ExcludeResSize);
239
240 unsigned i = 0;
241 for (Mapping::RangeIterator rei = LExclude.begin(),
242 e = LExclude.end(); rei != e; ++rei, ++i)
243 EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
244 } else
245 EXPECT_TRUE(LExclude.empty());
246 }
247
248 TEST(IntegersSubsetTest, DiffTest) {
249
250 static const unsigned NOT_A_NUMBER = 0xffff;
251
252 {
253 unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } };
254 unsigned_ranges RHS = { { 3, 14 } };
255 unsigned_ranges ExcludeRes = { { 0, 2 }, { 15, 17 } };
256 unsigned_ranges IntersectRes = { { 3, 4 }, { 7, 10 }, { 13, 14 } };
257
258 TestDiff(LHS, 3, RHS, 1, ExcludeRes, 2, IntersectRes, 3);
259 }
260
261 {
262 unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } };
263 unsigned_ranges RHS = { { 0, 4 }, { 13, 17 } };
264 unsigned_ranges ExcludeRes = { { 7, 10 } };
265 unsigned_ranges IntersectRes = { { 0, 4 }, { 13, 17 } };
266
267 TestDiff(LHS, 3, RHS, 2, ExcludeRes, 1, IntersectRes, 2);
268 }
269
270 {
271 unsigned_ranges LHS = { { 0, 17 } };
272 unsigned_ranges RHS = { { 1, 5 }, { 10, 12 }, { 15, 16 } };
273 unsigned_ranges ExcludeRes =
274 { { 0, 0 }, { 6, 9 }, { 13, 14 }, { 17, 17 } };
275 unsigned_ranges IntersectRes = { { 1, 5 }, { 10, 12 }, { 15, 16 } };
276
277 TestDiff(LHS, 1, RHS, 3, ExcludeRes, 4, IntersectRes, 3);
278 }
279
280 {
281 unsigned_ranges LHS = { { 2, 4 } };
282 unsigned_ranges RHS = { { 0, 5 } };
283 unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
284 unsigned_ranges IntersectRes = { { 2, 4 } };
285
286 TestDiff(LHS, 1, RHS, 1, ExcludeRes, 0, IntersectRes, 1);
287 }
288
289 {
290 unsigned_ranges LHS = { { 2, 4 } };
291 unsigned_ranges RHS = { { 7, 8 } };
292 unsigned_ranges ExcludeRes = { { 2, 4 } };
293 unsigned_ranges IntersectRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
294
295 TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0);
296 }
297
298 {
299 unsigned_ranges LHS = { { 3, 7 } };
300 unsigned_ranges RHS = { { 1, 4 } };
301 unsigned_ranges ExcludeRes = { { 5, 7 } };
302 unsigned_ranges IntersectRes = { { 3, 4 } };
303
304 TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 1);
305 }
306
307 {
308 unsigned_ranges LHS = { { 0, 7 } };
309 unsigned_ranges RHS = { { 0, 5 }, { 6, 9 } };
310 unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} };
311 unsigned_ranges IntersectRes = { { 0, 5 }, {6, 7} };
312
313 TestDiff(LHS, 1, RHS, 2, ExcludeRes, 0, IntersectRes, 2);
314 }
315
316 {
317 unsigned_ranges LHS = { { 17, 17 } };
318 unsigned_ranges RHS = { { 4, 4 } };
319 unsigned_ranges ExcludeRes = { {17, 17} };
320 unsigned_ranges IntersectRes = { { NOT_A_NUMBER, NOT_A_NUMBER } };
321
322 TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0);
323 }
324 }
325 }