llvm-6502/include/llvm/Support/IntegersSubset.h

541 lines
17 KiB
C
Raw Normal View History

//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// @file
/// This file contains class that implements constant set of ranges:
/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
/// SwitchInst and was used for case value representation that may contain
/// multiple ranges for a single successor.
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
//
//===----------------------------------------------------------------------===//
#ifndef CONSTANTRANGESSET_H_
#define CONSTANTRANGESSET_H_
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
#include "llvm/LLVMContext.h"
#include <list>
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
namespace llvm {
// The IntItem is a wrapper for APInt.
// 1. It determines sign of integer, it allows to use
// comparison operators >,<,>=,<=, and as result we got shorter and cleaner
// constructions.
// 2. It helps to implement PR1255 (case ranges) as a series of small patches.
// 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
// It allows to provide SwitchInst methods that works with ConstantInt for
// non-updated passes. And it allows to use APInt interface for new methods.
// 4. IntItem can be easily replaced with APInt.
// The set of macros that allows to propagate APInt operators to the IntItem.
#define INT_ITEM_DEFINE_COMPARISON(op,func) \
bool operator op (const APInt& RHS) const { \
return getAPIntValue().func(RHS); \
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
}
#define INT_ITEM_DEFINE_UNARY_OP(op) \
IntItem operator op () const { \
APInt res = op(getAPIntValue()); \
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
return IntItem(cast<ConstantInt>(NewVal)); \
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
}
#define INT_ITEM_DEFINE_BINARY_OP(op) \
IntItem operator op (const APInt& RHS) const { \
APInt res = getAPIntValue() op RHS; \
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
return IntItem(cast<ConstantInt>(NewVal)); \
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
}
#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
IntItem& operator op (const APInt& RHS) {\
APInt res = getAPIntValue();\
res op RHS; \
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
ConstantIntVal = cast<ConstantInt>(NewVal); \
return *this; \
}
#define INT_ITEM_DEFINE_PREINCDEC(op) \
IntItem& operator op () { \
APInt res = getAPIntValue(); \
op(res); \
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
ConstantIntVal = cast<ConstantInt>(NewVal); \
return *this; \
}
#define INT_ITEM_DEFINE_POSTINCDEC(op) \
IntItem& operator op (int) { \
APInt res = getAPIntValue();\
op(res); \
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
OldConstantIntVal = ConstantIntVal; \
ConstantIntVal = cast<ConstantInt>(NewVal); \
return IntItem(OldConstantIntVal); \
}
#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
RetTy operator op (IntTy RHS) const { \
return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
class IntItem {
ConstantInt *ConstantIntVal;
const APInt* APIntVal;
IntItem(const ConstantInt *V) :
ConstantIntVal(const_cast<ConstantInt*>(V)),
APIntVal(&ConstantIntVal->getValue()){}
const APInt& getAPIntValue() const {
return *APIntVal;
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
public:
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
IntItem() {}
operator const APInt&() const {
return getAPIntValue();
}
// Propagate APInt operators.
// Note, that
// /,/=,>>,>>= are not implemented in APInt.
// <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
INT_ITEM_DEFINE_COMPARISON(<, ult)
INT_ITEM_DEFINE_COMPARISON(>, ugt)
INT_ITEM_DEFINE_COMPARISON(<=, ule)
INT_ITEM_DEFINE_COMPARISON(>=, uge)
INT_ITEM_DEFINE_COMPARISON(==, eq)
INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
INT_ITEM_DEFINE_COMPARISON(!=, ne)
INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
INT_ITEM_DEFINE_BINARY_OP(*)
INT_ITEM_DEFINE_BINARY_OP(+)
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
INT_ITEM_DEFINE_BINARY_OP(-)
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
INT_ITEM_DEFINE_BINARY_OP(<<)
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
INT_ITEM_DEFINE_BINARY_OP(&)
INT_ITEM_DEFINE_BINARY_OP(^)
INT_ITEM_DEFINE_BINARY_OP(|)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
// Special case for <<=
IntItem& operator <<= (unsigned RHS) {
APInt res = getAPIntValue();
res <<= RHS;
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
ConstantIntVal = cast<ConstantInt>(NewVal);
return *this;
}
INT_ITEM_DEFINE_UNARY_OP(-)
INT_ITEM_DEFINE_UNARY_OP(~)
INT_ITEM_DEFINE_PREINCDEC(++)
INT_ITEM_DEFINE_PREINCDEC(--)
// The set of workarounds, since currently we use ConstantInt implemented
// integer.
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
static IntItem fromConstantInt(const ConstantInt *V) {
return IntItem(V);
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
}
static IntItem fromType(Type* Ty, const APInt& V) {
ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
return fromConstantInt(C);
}
static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
LikeThis.ConstantIntVal->getContext(), V));
return fromConstantInt(C);
}
ConstantInt *toConstantInt() const {
return ConstantIntVal;
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
}
};
template<class IntType>
class IntRange {
protected:
IntType Low;
IntType High;
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
bool IsEmpty : 1;
bool IsSingleNumber : 1;
public:
typedef IntRange<IntType> self;
typedef std::pair<self, self> SubRes;
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
IntRange() : IsEmpty(true) {}
IntRange(const self &RHS) :
Low(RHS.Low), High(RHS.High),
IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
IntRange(const IntType &C) :
Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
IsEmpty(false), IsSingleNumber(Low == High) {}
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
bool isEmpty() const { return IsEmpty; }
bool isSingleNumber() const { return IsSingleNumber; }
const IntType& getLow() const {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
assert(!IsEmpty && "Range is empty.");
return Low;
}
const IntType& getHigh() const {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
assert(!IsEmpty && "Range is empty.");
return High;
}
bool operator<(const self &RHS) const {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
assert(!IsEmpty && "Left range is empty.");
assert(!RHS.IsEmpty && "Right range is empty.");
if (Low == RHS.Low) {
if (High > RHS.High)
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
return true;
return false;
}
if (Low < RHS.Low)
return true;
return false;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
bool operator==(const self &RHS) const {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
assert(!IsEmpty && "Left range is empty.");
assert(!RHS.IsEmpty && "Right range is empty.");
return Low == RHS.Low && High == RHS.High;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
bool operator!=(const self &RHS) const {
return !operator ==(RHS);
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
static bool LessBySize(const self &LHS, const self &RHS) {
return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
bool isInRange(const IntType &IntVal) const {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
assert(!IsEmpty && "Range is empty.");
return IntVal >= Low && IntVal <= High;
}
SubRes sub(const self &RHS) const {
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
SubRes Res;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
// RHS is either more global and includes this range or
// if it doesn't intersected with this range.
if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
// If RHS more global (it is enough to check
// only one border in this case.
if (RHS.isInRange(Low))
return std::make_pair(self(Low, High), self());
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
return Res;
}
if (Low < RHS.Low) {
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
Res.first.Low = Low;
IntType NewHigh = RHS.Low;
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
--NewHigh;
Res.first.High = NewHigh;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
if (High > RHS.High) {
IntType NewLow = RHS.High;
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
++NewLow;
Res.second.Low = NewLow;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
Res.second.High = High;
}
return Res;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
};
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
//===----------------------------------------------------------------------===//
/// IntegersSubsetGeneric - class that implements the subset of integers. It
/// consists from ranges and single numbers.
template <class IntTy>
class IntegersSubsetGeneric {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
public:
// Use Chris Lattner idea, that was initially described here:
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
// In short, for more compact memory consumption we can store flat
// numbers collection, and define range as pair of indices.
// In that case we can safe some memory on 32 bit machines.
typedef std::vector<IntTy> FlatCollectionTy;
typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
typedef std::vector<RangeLinkTy> RangeLinksTy;
typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
typedef IntegersSubsetGeneric<IntTy> self;
protected:
FlatCollectionTy FlatCollection;
RangeLinksTy RangeLinks;
bool IsSingleNumber;
bool IsSingleNumbersOnly;
public:
template<class RangesCollectionTy>
explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
assert(Links.size() && "Empty ranges are not allowed.");
// In case of big set of single numbers consumes additional RAM space,
// but allows to avoid additional reallocation.
FlatCollection.reserve(Links.size() * 2);
RangeLinks.reserve(Links.size());
IsSingleNumbersOnly = true;
for (typename RangesCollectionTy::const_iterator i = Links.begin(),
e = Links.end(); i != e; ++i) {
RangeLinkTy RangeLink;
FlatCollection.push_back(i->getLow());
RangeLink.first = &FlatCollection.back();
if (i->getLow() != i->getHigh()) {
FlatCollection.push_back(i->getHigh());
IsSingleNumbersOnly = false;
}
RangeLink.second = &FlatCollection.back();
RangeLinks.push_back(RangeLink);
}
IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
}
IntegersSubsetGeneric(const self& RHS) {
*this = RHS;
}
self& operator=(const self& RHS) {
FlatCollection.clear();
RangeLinks.clear();
FlatCollection.reserve(RHS.RangeLinks.size() * 2);
RangeLinks.reserve(RHS.RangeLinks.size());
for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
i != e; ++i) {
RangeLinkTy RangeLink;
FlatCollection.push_back(*(i->first));
RangeLink.first = &FlatCollection.back();
if (i->first != i->second)
FlatCollection.push_back(*(i->second));
RangeLink.second = &FlatCollection.back();
RangeLinks.push_back(RangeLink);
}
IsSingleNumber = RHS.IsSingleNumber;
IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
return *this;
}
typedef IntRange<IntTy> Range;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// Checks is the given constant satisfies this case. Returns
/// true if it equals to one of contained values or belongs to the one of
/// contained ranges.
bool isSatisfies(const IntTy &CheckingVal) const {
if (IsSingleNumber)
return FlatCollection.front() == CheckingVal;
if (IsSingleNumbersOnly)
return std::find(FlatCollection.begin(),
FlatCollection.end(),
CheckingVal) != FlatCollection.end();
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
if (RangeLinks[i].first == RangeLinks[i].second) {
if (*RangeLinks[i].first == CheckingVal)
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
return true;
} else if (*RangeLinks[i].first <= CheckingVal &&
*RangeLinks[i].second >= CheckingVal)
return true;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
return false;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// Returns set's item with given index.
Range getItem(unsigned idx) const {
const RangeLinkTy &Link = RangeLinks[idx];
if (Link.first != Link.second)
return Range(*Link.first, *Link.second);
else
return Range(*Link.first);
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// Return number of items (ranges) stored in set.
unsigned getNumItems() const {
return RangeLinks.size();
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
/// Returns true if whole subset contains single element.
bool isSingleNumber() const {
return IsSingleNumber;
}
/// Returns true if whole subset contains only single numbers, no ranges.
bool isSingleNumbersOnly() const {
return IsSingleNumbersOnly;
}
/// Does the same like getItem(idx).isSingleNumber(), but
/// works faster, since we avoid creation of temporary range object.
bool isSingleNumber(unsigned idx) const {
return RangeLinks[idx].first == RangeLinks[idx].second;
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// Returns set the size, that equals number of all values + sizes of all
/// ranges.
/// Ranges set is considered as flat numbers collection.
/// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
/// for range [<0>, <1>, <5>] the size will 3
unsigned getSize() const {
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
const APInt Low = getItem(i).getLow();
const APInt High = getItem(i).getHigh();
APInt S = High - Low + 1;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
sz += S;
}
return sz.getZExtValue();
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// Allows to access single value even if it belongs to some range.
/// Ranges set is considered as flat numbers collection.
/// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
/// For range [<1>, <4,8>] getSingleValue(3) returns 6.
APInt getSingleValue(unsigned idx) const {
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
const APInt Low = getItem(i).getLow();
const APInt High = getItem(i).getHigh();
APInt S = High - Low + 1;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
APInt oldSz = sz;
sz += S;
if (sz.ugt(idx)) {
PR1255: Case Ranges Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now? 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst. 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case. 3. IntItem can be easyly easily replaced with APInt. 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes. Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code ConstantInt *V = ...; if (V->getValue().ugt(AnotherV->getValue()) { ... } will look awful. Much more better this way: IntItem V = ConstantIntVal->getValue(); if (AnotherV < V) { } Of course any reviews are welcome. P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks). Since in future these classes will founded on APInt, it will possible to use them in more generic ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157576 91177308-0d34-0410-b5e6-96231b3b80d8
2012-05-28 12:39:09 +00:00
APInt Res = Low;
APInt Offset(oldSz.getBitWidth(), idx);
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
Offset -= oldSz;
Res += Offset;
return Res;
}
}
assert(0 && "Index exceeds high border.");
return sz;
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
/// Does the same as getSingleValue, but works only if subset contains
/// single numbers only.
const IntTy& getSingleNumber(unsigned idx) const {
assert(IsSingleNumbersOnly && "This method works properly if subset "
"contains single numbers only.");
return FlatCollection[idx];
}
};
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
//===----------------------------------------------------------------------===//
/// IntegersSubset - currently is extension of IntegersSubsetGeneric
/// that also supports conversion to/from Constant* object.
class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
typedef IntegersSubsetGeneric<IntItem> ParentTy;
Constant *Holder;
static unsigned getNumItemsFromConstant(Constant *C) {
return cast<ArrayType>(C->getType())->getNumElements();
}
static Range getItemFromConstant(Constant *C, unsigned idx) {
const Constant *CV = C->getAggregateElement(idx);
unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
switch (NumEls) {
case 1:
return Range(IntItem::fromConstantInt(
cast<ConstantInt>(CV->getAggregateElement(0U))),
IntItem::fromConstantInt(cast<ConstantInt>(
cast<ConstantInt>(CV->getAggregateElement(0U)))));
case 2:
return Range(IntItem::fromConstantInt(
cast<ConstantInt>(CV->getAggregateElement(0U))),
IntItem::fromConstantInt(
cast<ConstantInt>(CV->getAggregateElement(1))));
default:
assert(0 && "Only pairs and single numbers are allowed here.");
return Range();
}
}
std::vector<Range> rangesFromConstant(Constant *C) {
unsigned NumItems = getNumItemsFromConstant(C);
std::vector<Range> r;
r.reserve(NumItems);
for (unsigned i = 0, e = NumItems; i != e; ++i)
r.push_back(getItemFromConstant(C, i));
return r;
}
public:
explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
Holder(C) {}
IntegersSubset(const IntegersSubset& RHS) :
ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
Holder(RHS.Holder) {}
template<class RangesCollectionTy>
explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
std::vector<Constant*> Elts;
Elts.reserve(Src.size());
for (typename RangesCollectionTy::const_iterator i = Src.begin(),
e = Src.end(); i != e; ++i) {
const Range &R = *i;
std::vector<Constant*> r;
if (R.isSingleNumber()) {
r.reserve(2);
// FIXME: Since currently we have ConstantInt based numbers
// use hack-conversion of IntItem to ConstantInt
r.push_back(R.getLow().toConstantInt());
r.push_back(R.getHigh().toConstantInt());
} else {
r.reserve(1);
r.push_back(R.getLow().toConstantInt());
}
Constant *CV = ConstantVector::get(r);
Elts.push_back(CV);
}
ArrayType *ArrTy =
ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
Holder = ConstantArray::get(ArrTy, Elts);
}
operator Constant*() { return Holder; }
operator const Constant*() const { return Holder; }
Constant *operator->() { return Holder; }
const Constant *operator->() const { return Holder; }
};
Related to PR1255. Let's begin. I'll commit classes that corresponds to our latest PR1255 discussion posts in llvm-commits. Strategy. 0. Implement new classes. Classes doesn't affect anything. They still work with ConstantInt base values at this stage. 1. Fictitious replacement of current ConstantInt case values with ConstantRangesSet. Case ranges set will still hold single value, and ConstantInt *getCaseValue() will return it. But additionally implement new method in SwitchInst that allows to work with case ranges. Currenly I think it should be some wrapper that returns either single value or ConstantRangesSet object. 2. Step-by-step replacement of old "ConstantInt* getCaseValue()" with new alternative. Modify algorithms for all passes that works with SwitchInst. But don't modify LLParser and BitcodeReader/Writer. Still hold single value in each ConstantRangesSet object. On this stage some parts of LLVM will use old-style methods, and some ones new-style. 3. After all getCaseValue() usages will removed and whole LLVM and its clients will work in new style - modify LLParser, Reader and Writer. Remove getCaseValue(). 4. Replace ConstantInt*-based case ranges set items with APInt ones. Currently we are on Zero Stage: New classes. ConstantRangesSet. I selected ConstantArrays as case ranges set "holder" object (it is a temporary decision, I'll explain why below). The array items are may be ConstantVectors with single item, and ConstantVectors with two items (that means single number and range respectively). The ConstantInt will used as basic value representation. It will replaced with APInt then. Of course ConstantArray and ConstantVector will go away after ConstantInt => APInt replacement. New class mandatory features: - bool isSatisfies(ConstantInt *V) method (need better name?). Returns true if the given value satisfies this case. - Case's ranges and values enumeration. In some passes we need to analize each case (SwitchLowering for example). Factory + unified clusterify. I also propose to implement the factory that allows to build case object with user friendly way. I called it CRSBuilder by now. Currenly I implemented the factory that allows add,remove pairs of range+successor. It also allows add existing ConstantRangesSet decompiling it to separated ranges. Factory can emit either clusters set (single case range + successor) or the set of "ConstantRangesSet + Successor" pairs. So you can use it either as builder for new cases set for SwitchInst, or for clusterification of existing cases set. Just call Factory.optimize() and it emits optimized and sorted clusters collection for you! I tested clusterification on SelectionDAGBuilder - it works fine. Don't worry it was not included in this patch. Just new classes. Factory is a template. There are two params: SuccessorClass and IsReadonly. So you can specify what successor you need (BB or MBB). And you can also restrict your factory to use values in read-only mode (SelectionDAGBuilder need IsReadonly=true). Read-only factory couldn't build the cases ranges. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155464 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-24 18:31:10 +00:00
}
#endif /* CONSTANTRANGESSET_H_ */