[llvm-commits] [llvm] r159527 - in /llvm/trunk: include/llvm/Support/IntegersSubset.h include/llvm/Support/IntegersSubsetMapping.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Transforms/Utils/LowerSwitch.cpp lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll unittests/Support/IntegersSubsetTest.cpp
Stepan Dyatkovskiy
stpworld at narod.ru
Tue Jul 3 00:26:56 PDT 2012
OK. Thanks.
-Stepan.
Eric Christopher wrote:
> I've gone ahead and reverted this commit. Let me know if the tree doesn't come back.
>
> -eric
>
> On Jul 2, 2012, at 2:15 PM, David Dean <david_dean at apple.com> wrote:
>
>> I'm seeing a crash when self-hosting a Release+Asserts build on darwin after this commit:
>>
>> Assertion failed: (getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"), function ICmpInst, file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/llvm/include/llvm/Instructions.h, line 960.
>> 0 clang 0x000000010157c732 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 14386
>> 1 clang 0x000000010157cc14 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 15636
>> 2 libSystem.B.dylib 0x00007fff868441ba _sigtramp + 26
>> 3 libSystem.B.dylib 0x522d706172747374 _sigtramp + 3958387156
>> 4 clang 0x000000010157c976 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 14966
>> 5 clang 0x000000010157c951 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 14929
>> 6 clang 0x00000001011e02f2 std::_Rb_tree<llvm::BasicBlock*, llvm::BasicBlock*, std::_Identity<llvm::BasicBlock*>, std::less<llvm::BasicBlock*>, std::allocator<llvm::BasicBlock*> >::_M_insert_unique(llvm::BasicBlock* const&) + 4978
>> 7 clang 0x0000000100af7abe std::_Rb_tree<std::pair<llvm::Value*, llvm::Value*>, std::pair<std::pair<llvm::Value*, llvm::Value*> const, std::pair<llvm::Value*, llvm::Value*> >, std::_Select1st<std::pair<std::pair<llvm::Value*, llvm::Value*> const, std::pair<llvm::Value*, llvm::Value*> > >, std::less<std::pair<llvm::Value*, llvm::Value*> >, std::allocator<std::pair<std::pair<llvm::Value*, llvm::Value*> const, std::pair<llvm::Value*, llvm::Value*> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::pair<llvm::Value*, llvm::Value*> const, std::pair<llvm::Value*, llvm::Value*> > >*) + 53630
>> 8 clang 0x00000001012fa1ba int llvm::array_pod_sort_comparator<llvm::BasicBlock*>(void const*, void const*) + 1866
>> 9 clang 0x000000010131b45f void std::__heap_select<std::pair<unsigned int, llvm::StoreInst*>*>(std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*) + 32751
>> 10 clang 0x000000010131fc09 void std::__heap_select<std::pair<unsigned int, llvm::StoreInst*>*>(std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*) + 51097
>> 11 clang 0x000000010131b38b void std::__heap_select<std::pair<unsigned int, llvm::StoreInst*>*>(std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*, std::pair<unsigned int, llvm::StoreInst*>*) + 32539
>> 12 clang 0x00000001012776ab std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > > std::__copy_aux<llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > > >(llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > >) + 100363
>> 13 clang 0x0000000101276b6e std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > > std::__copy_aux<llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > > >(llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, llvm::po_iterator<llvm::BasicBlock*, llvm::SmallPtrSet<llvm::BasicBlock*, 8u>, false, llvm::GraphTraits<llvm::BasicBlock*> >, std::back_insert_iterator<std::vector<llvm::BasicBlock*, std::allocator<llvm::BasicBlock*> > >) + 97486
>> 14 clang 0x000000010151fa60 std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 28736
>> 15 clang 0x00000001013321ea std::vector<std::pair<llvm::WeakVH, llvm::CallGraphNode*>, std::allocator<std::pair<llvm::WeakVH, llvm::CallGraphNode*> > >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::pair<llvm::WeakVH, llvm::CallGraphNode*>*, std::vector<std::pair<llvm::WeakVH, llvm::CallGraphNode*>, std::allocator<std::pair<llvm::WeakVH, llvm::CallGraphNode*> > > >, std::pair<llvm::WeakVH, llvm::CallGraphNode*> const&) + 4762
>> 16 clang 0x000000010151ff56 std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 30006
>> 17 clang 0x0000000101520519 std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 31481
>> 18 clang 0x00000001015206fd std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 31965
>> 19 clang 0x000000010015f29a std::vector<clang::serialization::ModuleFile*, std::allocator<clang::serialization::ModuleFile*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::serialization::ModuleFile**, std::vector<clang::serialization::ModuleFile*, std::allocator<clang::serialization::ModuleFile*> > >, clang::serialization::ModuleFile* const&) + 7626
>> 20 clang 0x000000010024183a llvm::ParseIR(llvm::MemoryBuffer*, llvm::SMDiagnostic&, llvm::LLVMContext&) + 1994
>> 21 clang 0x0000000100278044 std::vector<std::pair<llvm::WeakVH, llvm::Constant*>, std::allocator<std::pair<llvm::WeakVH, llvm::Constant*> > >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::pair<llvm::WeakVH, llvm::Constant*>*, std::vector<std::pair<llvm::WeakVH, llvm::Constant*>, std::allocator<std::pair<llvm::WeakVH, llvm::Constant*> > > >, std::pair<llvm::WeakVH, llvm::Constant*> const&) + 53652
>> 22 clang 0x0000000100240480 std::vector<clang::CXXRecordDecl const*, std::allocator<clang::CXXRecordDecl const*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::CXXRecordDecl const**, std::vector<clang::CXXRecordDecl const*, std::allocator<clang::CXXRecordDecl const*> > >, clang::CXXRecordDecl const* const&) + 6128
>> 23 clang 0x000000010004df28 llvm::SmallVectorImpl<clang::FileEntry const*>::operator=(llvm::SmallVectorImpl<clang::FileEntry const*> const&) + 10168
>> 24 clang 0x00000001000247bf std::vector<clang::CompilerInstance*, std::allocator<clang::CompilerInstance*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::CompilerInstance**, std::vector<clang::CompilerInstance*, std::allocator<clang::CompilerInstance*> > >, clang::CompilerInstance* const&) + 16431
>> 25 clang 0x000000010000b161 std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_unique(std::string const&) + 3921
>> 26 clang 0x0000000100000d1a
>> 27 clang 0x0000000100007bfc std::vector<std::string, std::allocator<std::string> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, std::string const&) + 4124
>> 28 clang 0x0000000100000a34
>> 29 clang 0x0000000000000051
>> Stack dump:
>> 0. Program arguments: /Users/buildslave/zorg/bui
>> ldbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/host-compiler/bin/clang -cc1 -triple x86_64-apple-macosx10.6.0 -emit-obj -disable-free -main-file-name Metadata.cpp -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 127.2.1 -coverage-file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore/Release+Asserts/Metadata.o -resource-dir /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/host-compiler/bin/../lib/clang/3.2 -dependency-file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore/Release+Asserts/Metadata.d.tmp -MP -MT /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore/Release+Asserts/Metadata.o -MT /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore/Release+Asserts/Met
ad!
>> ata.d -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/include -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/llvm/include -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/llvm/lib/VMCore -fmodule-cache-path /var/folders/71/71mRDn96FOKuiuacJNrmGU+++TM/-Tmp-/clang-module-cache -O3 -Woverloaded-virtual -Wcast-qual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcovered-switch-default -pedantic -fconst-strings -fdeprecated-macro -fdebug-compilation-dir /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protecto
r!
>> 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.6.0 -fobjc-dispatc
>> h-method=mixed -fobjc-default-synthesize-properties -fno-common -fdiagnostics-show-option -o /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/clang-build/lib/VMCore/Release+Asserts/Metadata.o -x c++ /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/llvm/lib/VMCore/Metadata.cpp
>> 1. <eof> parser at end of file
>> 2. Per-module optimization passes
>> 3. Running pass 'CallGraph Pass Manager' on module '/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-RA/llvm/lib/VMCore/Metadata.cpp'.
>> 4. Running pass 'Simplify the CFG' on function '@_ZNK4llvm10TrackingVHINS_6MDNodeEE13CheckValidityEv'
>>
>>
>>
>>
>> On 2 Jul 2012, at 6:02 AM, Stepan Dyatkovskiy wrote:
>>
>>> Author: dyatkovskiy
>>> Date: Mon Jul 2 08:02:18 2012
>>> New Revision: 159527
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=159527&view=rev
>>> Log:
>>> IntRange:
>>> - Changed isSingleNumber method behaviour. Now this flag is calculated on demand.
>>> IntegersSubsetMapping
>>> - Optimized diff operation.
>>> - Replaced type of Items field from std::list with std::map.
>>> - Added new methods:
>>> bool isOverlapped(self &RHS)
>>> void add(self& RHS, SuccessorClass *S)
>>> void detachCase(self& NewMapping, SuccessorClass *Succ)
>>> void removeCase(SuccessorClass *Succ)
>>> SuccessorClass *findSuccessor(const IntTy& Val)
>>> const IntTy* getCaseSingleNumber(SuccessorClass *Succ)
>>> IntegersSubsetTest
>>> - DiffTest: Added checks for successors.
>>> SimplifyCFG
>>> Updated SwitchInst usage (now it is case-ragnes compatible) for
>>> - SimplifyEqualityComparisonWithOnlyPredecessor
>>> - FoldValueComparisonIntoPredecessors
>>>
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/Support/IntegersSubset.h
>>> llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>>> llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
>>> llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
>>> llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll
>>> llvm/trunk/unittests/Support/IntegersSubsetTest.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/Support/IntegersSubset.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubset.h?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/IntegersSubset.h (original)
>>> +++ llvm/trunk/include/llvm/Support/IntegersSubset.h Mon Jul 2 08:02:18 2012
>>> @@ -182,7 +182,12 @@
>>> IntType Low;
>>> IntType High;
>>> bool IsEmpty : 1;
>>> - bool IsSingleNumber : 1;
>>> + enum Type {
>>> + SINGLE_NUMBER,
>>> + RANGE,
>>> + UNKNOWN
>>> + };
>>> + Type RangeType;
>>>
>>> public:
>>> typedef IntRange<IntType> self;
>>> @@ -191,15 +196,30 @@
>>> IntRange() : IsEmpty(true) {}
>>> IntRange(const self &RHS) :
>>> Low(RHS.Low), High(RHS.High),
>>> - IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
>>> + IsEmpty(RHS.IsEmpty), RangeType(RHS.RangeType) {}
>>> IntRange(const IntType &C) :
>>> - Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
>>> + Low(C), High(C), IsEmpty(false), RangeType(SINGLE_NUMBER) {}
>>>
>>> IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
>>> - IsEmpty(false), IsSingleNumber(Low == High) {}
>>> + IsEmpty(false), RangeType(UNKNOWN) {}
>>>
>>> bool isEmpty() const { return IsEmpty; }
>>> - bool isSingleNumber() const { return IsSingleNumber; }
>>> + bool isSingleNumber() const {
>>> + switch (RangeType) {
>>> + case SINGLE_NUMBER:
>>> + return true;
>>> + case RANGE:
>>> + return false;
>>> + case UNKNOWN:
>>> + default:
>>> + if (Low == High) {
>>> + const_cast<Type&>(RangeType) = SINGLE_NUMBER;
>>> + return true;
>>> + }
>>> + const_cast<Type&>(RangeType) = RANGE;
>>> + return false;
>>> + }
>>> + }
>>>
>>> const IntType& getLow() const {
>>> assert(!IsEmpty && "Range is empty.");
>>> @@ -213,13 +233,13 @@
>>> bool operator<(const self &RHS) const {
>>> assert(!IsEmpty && "Left range is empty.");
>>> assert(!RHS.IsEmpty && "Right range is empty.");
>>> + if (Low < RHS.Low)
>>> + return true;
>>> if (Low == RHS.Low) {
>>> if (High > RHS.High)
>>> return true;
>>> return false;
>>> }
>>> - if (Low < RHS.Low)
>>> - return true;
>>> return false;
>>> }
>>>
>>> @@ -512,7 +532,7 @@
>>> e = Src.end(); i != e; ++i) {
>>> const Range &R = *i;
>>> std::vector<Constant*> r;
>>> - if (R.isSingleNumber()) {
>>> + if (!R.isSingleNumber()) {
>>> r.reserve(2);
>>> // FIXME: Since currently we have ConstantInt based numbers
>>> // use hack-conversion of IntItem to ConstantInt
>>>
>>> Modified: llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h (original)
>>> +++ llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h Mon Jul 2 08:02:18 2012
>>> @@ -58,22 +58,16 @@
>>>
>>> protected:
>>>
>>> - typedef std::list<Cluster> CaseItems;
>>> + typedef std::map<RangeEx, SuccessorClass*> CaseItems;
>>> typedef typename CaseItems::iterator CaseItemIt;
>>> typedef typename CaseItems::const_iterator CaseItemConstIt;
>>>
>>> // TODO: Change unclean CRS prefixes to SubsetMap for example.
>>> typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
>>> typedef typename CRSMap::iterator CRSMapIt;
>>> -
>>> - struct ClustersCmp {
>>> - bool operator()(const Cluster &C1, const Cluster &C2) {
>>> - return C1.first < C2.first;
>>> - }
>>> - };
>>>
>>> CaseItems Items;
>>> - bool Sorted;
>>> + bool SingleNumbersOnly;
>>>
>>> bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
>>> return LItem->first.getHigh() >= RItem->first.getLow();
>>> @@ -91,18 +85,6 @@
>>> return LItem->first.getHigh() >= RLow;
>>> }
>>>
>>> - void sort() {
>>> - if (!Sorted) {
>>> - std::vector<Cluster> clustersVector;
>>> - clustersVector.reserve(Items.size());
>>> - clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
>>> - std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
>>> - Items.clear();
>>> - Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
>>> - Sorted = true;
>>> - }
>>> - }
>>> -
>>> enum DiffProcessState {
>>> L_OPENED,
>>> INTERSECT_OPENED,
>>> @@ -213,7 +195,7 @@
>>> }
>>> }
>>>
>>> - void onRLOpen(const IntTy &Pt,
>>> + void onLROpen(const IntTy &Pt,
>>> SuccessorClass *LS,
>>> SuccessorClass *RS) {
>>> switch (State) {
>>> @@ -229,7 +211,7 @@
>>> OpenPt = Pt;
>>> }
>>>
>>> - void onRLClose(const IntTy &Pt) {
>>> + void onLRClose(const IntTy &Pt) {
>>> switch (State) {
>>> case INTERSECT_OPENED:
>>> if (IntersectionMapping)
>>> @@ -245,6 +227,48 @@
>>> bool isLOpened() { return State == L_OPENED; }
>>> bool isROpened() { return State == R_OPENED; }
>>> };
>>> +
>>> + void diff_single_numbers(self *LExclude, self *Intersection, self *RExclude,
>>> + const self& RHS) {
>>> +
>>> + CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
>>> + CaseItemConstIt el = Items.end(), er = RHS.Items.end();
>>> + while (L != el && R != er) {
>>> + const Cluster &LCluster = *L;
>>> + const RangeEx &LRange = LCluster.first;
>>> + const Cluster &RCluster = *R;
>>> + const RangeEx &RRange = RCluster.first;
>>> +
>>> + if (LRange.getLow() < RRange.getLow()) {
>>> + if (LExclude)
>>> + LExclude->add(LRange.getLow(), LCluster.second);
>>> + ++L;
>>> + } else if (LRange.getLow() > RRange.getLow()) {
>>> + if (RExclude)
>>> + RExclude->add(RRange.getLow(), RCluster.second);
>>> + ++R;
>>> + } else {
>>> + if (Intersection)
>>> + Intersection->add(LRange.getLow(), LCluster.second);
>>> + ++L;
>>> + ++R;
>>> + }
>>> + }
>>> +
>>> + if (L != Items.end()) {
>>> + if (LExclude)
>>> + do {
>>> + LExclude->add(L->first, L->second);
>>> + ++L;
>>> + } while (L != Items.end());
>>> + } else if (R != RHS.Items.end()) {
>>> + if (RExclude)
>>> + do {
>>> + RExclude->add(R->first, R->second);
>>> + ++R;
>>> + } while (R != RHS.Items.end());
>>> + }
>>> + }
>>>
>>> public:
>>>
>>> @@ -256,15 +280,18 @@
>>>
>>> typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
>>> typedef std::list<Case> Cases;
>>> + typedef typename Cases::iterator CasesIt;
>>> +
>>> + IntegersSubsetMapping() : SingleNumbersOnly(true) {}
>>>
>>> - IntegersSubsetMapping() {
>>> - Sorted = false;
>>> + bool verify() {
>>> + RangeIterator DummyErrItem;
>>> + return verify(DummyErrItem);
>>> }
>>>
>>> bool verify(RangeIterator& errItem) {
>>> if (Items.empty())
>>> return true;
>>> - sort();
>>> for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
>>> j != e; i = j++) {
>>> if (isIntersected(i, j) && i->second != j->second) {
>>> @@ -275,10 +302,36 @@
>>> return true;
>>> }
>>>
>>> + bool isOverlapped(self &RHS) {
>>> + if (Items.empty() || RHS.empty())
>>> + return true;
>>> +
>>> + for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
>>> + el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
>>> +
>>> + const RangeTy &LRange = L->first;
>>> + const RangeTy &RRange = R->first;
>>> +
>>> + if (LRange.getLow() > RRange.getLow()) {
>>> + if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
>>> + ++R;
>>> + else
>>> + return true;
>>> + } else if (LRange.getLow() < RRange.getLow()) {
>>> + if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
>>> + ++L;
>>> + else
>>> + return true;
>>> + } else // iRange.getLow() == jRange.getLow()
>>> + return true;
>>> + }
>>> + return false;
>>> + }
>>> +
>>> +
>>> void optimize() {
>>> if (Items.size() < 2)
>>> return;
>>> - sort();
>>> CaseItems OldItems = Items;
>>> Items.clear();
>>> const IntTy *Low = &OldItems.begin()->first.getLow();
>>> @@ -303,8 +356,6 @@
>>> }
>>> RangeEx R(*Low, *High, Weight);
>>> add(R, Successor);
>>> - // We recollected the Items, but we kept it sorted.
>>> - Sorted = true;
>>> }
>>>
>>> /// Adds a constant value.
>>> @@ -323,8 +374,10 @@
>>> add(REx, S);
>>> }
>>> void add(const RangeEx &R, SuccessorClass *S = 0) {
>>> - Items.push_back(std::make_pair(R, S));
>>> - Sorted = false;
>>> + //Items.push_back(std::make_pair(R, S));
>>> + Items.insert(std::make_pair(R, S));
>>> + if (!R.isSingleNumber())
>>> + SingleNumbersOnly = false;
>>> }
>>>
>>> /// Adds all ranges and values from given ranges set to the current
>>> @@ -337,9 +390,17 @@
>>> }
>>>
>>> void add(self& RHS) {
>>> - Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
>>> + //Items.insert(Items.begin(), RHS.Items.begin(), RHS.Items.end());
>>> + Items.insert(RHS.Items.begin(), RHS.Items.end());
>>> + if (!RHS.SingleNumbersOnly)
>>> + SingleNumbersOnly = false;
>>> }
>>>
>>> + void add(self& RHS, SuccessorClass *S) {
>>> + for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
>>> + add(i->first, S);
>>> + }
>>> +
>>> void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
>>> for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
>>> add(*i, S);
>>> @@ -348,6 +409,34 @@
>>> /// Removes items from set.
>>> void removeItem(RangeIterator i) { Items.erase(i); }
>>>
>>> + /// Moves whole case from current mapping to the NewMapping object.
>>> + void detachCase(self& NewMapping, SuccessorClass *Succ) {
>>> + for (CaseItemIt i = Items.begin(); i != Items.end();)
>>> + if (i->second == Succ) {
>>> + NewMapping.add(i->first, i->second);
>>> + Items.erase(i++);
>>> + } else
>>> + ++i;
>>> + }
>>> +
>>> + /// Removes all clusters for given successor.
>>> + void removeCase(SuccessorClass *Succ) {
>>> + for (CaseItemIt i = Items.begin(); i != Items.end();)
>>> + if (i->second == Succ) {
>>> + Items.erase(i++);
>>> + } else
>>> + ++i;
>>> + }
>>> +
>>> + /// Find successor that satisfies given value.
>>> + SuccessorClass *findSuccessor(const IntTy& Val) {
>>> + for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
>>> + if (i->first.isInRange(Val))
>>> + return i->second;
>>> + }
>>> + return 0;
>>> + }
>>> +
>>> /// Calculates the difference between this mapping and RHS.
>>> /// THIS without RHS is placed into LExclude,
>>> /// RHS without THIS is placed into RExclude,
>>> @@ -355,10 +444,16 @@
>>> void diff(self *LExclude, self *Intersection, self *RExclude,
>>> const self& RHS) {
>>>
>>> + if (SingleNumbersOnly && RHS.SingleNumbersOnly) {
>>> + diff_single_numbers(LExclude, Intersection, RExclude, RHS);
>>> + return;
>>> + }
>>> +
>>> DiffStateMachine Machine(LExclude, Intersection, RExclude);
>>>
>>> CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
>>> - while (L != Items.end() && R != RHS.Items.end()) {
>>> + CaseItemConstIt el = Items.end(), er = RHS.Items.end();
>>> + while (L != el && R != er) {
>>> const Cluster &LCluster = *L;
>>> const RangeEx &LRange = LCluster.first;
>>> const Cluster &RCluster = *R;
>>> @@ -377,7 +472,36 @@
>>> ++R;
>>> continue;
>>> }
>>> +
>>> + if (LRange.isSingleNumber() && RRange.isSingleNumber()) {
>>> + Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
>>> + Machine.onLRClose(LRange.getLow());
>>> + ++L;
>>> + ++R;
>>> + continue;
>>> + }
>>>
>>> + if (LRange.isSingleNumber()) {
>>> + Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> + Machine.onLClose(LRange.getLow());
>>> + ++L;
>>> + while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
>>> + Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> + Machine.onLClose(LRange.getLow());
>>> + ++L;
>>> + }
>>> + continue;
>>> + } else if (RRange.isSingleNumber()) {
>>> + Machine.onROpen(R->first.getLow(), R->second);
>>> + Machine.onRClose(R->first.getHigh());
>>> + ++R;
>>> + while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
>>> + Machine.onROpen(R->first.getLow(), R->second);
>>> + Machine.onRClose(R->first.getHigh());
>>> + ++R;
>>> + }
>>> + continue;
>>> + } else
>>> if (LRange.getLow() < RRange.getLow()) {
>>> // May be opened in previous iteration.
>>> if (!Machine.isLOpened())
>>> @@ -390,7 +514,7 @@
>>> Machine.onLOpen(LRange.getLow(), LCluster.second);
>>> }
>>> else
>>> - Machine.onRLOpen(LRange.getLow(), LCluster.second, RCluster.second);
>>> + Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
>>>
>>> if (LRange.getHigh() < RRange.getHigh()) {
>>> Machine.onLClose(LRange.getHigh());
>>> @@ -411,7 +535,7 @@
>>> }
>>> }
>>> else {
>>> - Machine.onRLClose(LRange.getHigh());
>>> + Machine.onLRClose(LRange.getHigh());
>>> ++L;
>>> ++R;
>>> }
>>> @@ -441,7 +565,20 @@
>>> }
>>>
>>> /// Builds the finalized case objects.
>>> - void getCases(Cases& TheCases) {
>>> + void getCases(Cases& TheCases, bool PreventMerging = false) {
>>> + //FIXME: PreventMerging is a temporary parameter.
>>> + //Currently a set of passes is still knows nothing about
>>> + //switches with case ranges, and if these passes meet switch
>>> + //with complex case that crashs the application.
>>> + if (PreventMerging) {
>>> + for (RangeIterator i = this->begin(); i != this->end(); ++i) {
>>> + RangesCollection SingleRange;
>>> + SingleRange.push_back(i->first);
>>> + TheCases.push_back(std::make_pair(i->second,
>>> + IntegersSubsetTy(SingleRange)));
>>> + }
>>> + return;
>>> + }
>>> CRSMap TheCRSMap;
>>> for (RangeIterator i = this->begin(); i != this->end(); ++i)
>>> TheCRSMap[i->second].push_back(i->first);
>>> @@ -458,6 +595,22 @@
>>> return IntegersSubsetTy(Ranges);
>>> }
>>>
>>> + /// Returns pointer to value of case if it is single-numbered or 0
>>> + /// in another case.
>>> + const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
>>> + const IntTy* Res = 0;
>>> + for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
>>> + if (i->second == Succ) {
>>> + if (!i->first.isSingleNumber())
>>> + return 0;
>>> + if (Res)
>>> + return 0;
>>> + else
>>> + Res = &(i->first.getLow());
>>> + }
>>> + return Res;
>>> + }
>>> +
>>> /// Returns true if there is no ranges and values inside.
>>> bool empty() const { return Items.empty(); }
>>>
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Jul 2 08:02:18 2012
>>> @@ -2450,22 +2450,23 @@
>>> size_t numCmps = 0;
>>> for (Clusterifier::RangeIterator i = TheClusterifier.begin(),
>>> e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
>>> - Clusterifier::Cluster &C = *i;
>>> + const Clusterifier::RangeEx &R = i->first;
>>> + MachineBasicBlock *MBB = i->second;
>>> unsigned W = 0;
>>> if (BPI) {
>>> - W = BPI->getEdgeWeight(SI.getParent(), C.second->getBasicBlock());
>>> + W = BPI->getEdgeWeight(SI.getParent(), MBB->getBasicBlock());
>>> if (!W)
>>> W = 16;
>>> - W *= C.first.Weight;
>>> - BPI->setEdgeWeight(SI.getParent(), C.second->getBasicBlock(), W);
>>> + W *= R.Weight;
>>> + BPI->setEdgeWeight(SI.getParent(), MBB->getBasicBlock(), W);
>>> }
>>>
>>> // FIXME: Currently work with ConstantInt based numbers.
>>> // Changing it to APInt based is a pretty heavy for this commit.
>>> - Cases.push_back(Case(C.first.getLow().toConstantInt(),
>>> - C.first.getHigh().toConstantInt(), C.second, W));
>>> + Cases.push_back(Case(R.getLow().toConstantInt(),
>>> + R.getHigh().toConstantInt(), MBB, W));
>>>
>>> - if (C.first.getLow() != C.first.getHigh())
>>> + if (R.getLow() != R.getHigh())
>>> // A range counts double, since it requires two compares.
>>> ++numCmps;
>>> }
>>>
>>> Modified: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp Mon Jul 2 08:02:18 2012
>>> @@ -238,13 +238,14 @@
>>> size_t numCmps = 0;
>>> for (IntegersSubsetToBB::RangeIterator i = TheClusterifier.begin(),
>>> e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
>>> - IntegersSubsetToBB::Cluster &C = *i;
>>> + const IntegersSubsetToBB::RangeTy &R = i->first;
>>> + BasicBlock *S = i->second;
>>>
>>> // FIXME: Currently work with ConstantInt based numbers.
>>> // Changing it to APInt based is a pretty heavy for this commit.
>>> - Cases.push_back(CaseRange(C.first.getLow().toConstantInt(),
>>> - C.first.getHigh().toConstantInt(), C.second));
>>> - if (C.first.isSingleNumber())
>>> + Cases.push_back(CaseRange(R.getLow().toConstantInt(),
>>> + R.getHigh().toConstantInt(), S));
>>> + if (R.isSingleNumber())
>>> // A range counts double, since it requires two compares.
>>> ++numCmps;
>>> }
>>>
>>> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Jul 2 08:02:18 2012
>>> @@ -56,26 +56,12 @@
>>> STATISTIC(NumSpeculations, "Number of speculative executed instructions");
>>>
>>> namespace {
>>> - /// ValueEqualityComparisonCase - Represents a case of a switch.
>>> - struct ValueEqualityComparisonCase {
>>> - ConstantInt *Value;
>>> - BasicBlock *Dest;
>>> -
>>> - ValueEqualityComparisonCase(ConstantInt *Value, BasicBlock *Dest)
>>> - : Value(Value), Dest(Dest) {}
>>> -
>>> - bool operator<(ValueEqualityComparisonCase RHS) const {
>>> - // Comparing pointers is ok as we only rely on the order for uniquing.
>>> - return Value < RHS.Value;
>>> - }
>>> - };
>>> -
>>> class SimplifyCFGOpt {
>>> const TargetData *const TD;
>>>
>>> Value *isValueEqualityComparison(TerminatorInst *TI);
>>> BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
>>> - std::vector<ValueEqualityComparisonCase> &Cases);
>>> + IntegersSubsetToBB &Mapping);
>>> bool SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
>>> BasicBlock *Pred,
>>> IRBuilder<> &Builder);
>>> @@ -532,72 +518,25 @@
>>> /// decode all of the 'cases' that it represents and return the 'default' block.
>>> BasicBlock *SimplifyCFGOpt::
>>> GetValueEqualityComparisonCases(TerminatorInst *TI,
>>> - std::vector<ValueEqualityComparisonCase>
>>> - &Cases) {
>>> + IntegersSubsetToBB &Mapping) {
>>> if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
>>> - Cases.reserve(SI->getNumCases());
>>> - for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i)
>>> - Cases.push_back(ValueEqualityComparisonCase(i.getCaseValue(),
>>> - i.getCaseSuccessor()));
>>> + for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
>>> + i != e; ++i)
>>> + Mapping.add(i.getCaseValueEx(), i.getCaseSuccessor());
>>> return SI->getDefaultDest();
>>> }
>>> -
>>> +
>>> BranchInst *BI = cast<BranchInst>(TI);
>>> ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
>>> - BasicBlock *Succ = BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_NE);
>>> - Cases.push_back(ValueEqualityComparisonCase(GetConstantInt(ICI->getOperand(1),
>>> - TD),
>>> - Succ));
>>> + IntegersSubsetToBB Builder;
>>> +
>>> + Mapping.add(
>>> + IntItem::fromConstantInt(GetConstantInt(ICI->getOperand(1), TD)),
>>> + BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_NE));
>>> +
>>> return BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_EQ);
>>> }
>>>
>>> -
>>> -/// EliminateBlockCases - Given a vector of bb/value pairs, remove any entries
>>> -/// in the list that match the specified block.
>>> -static void EliminateBlockCases(BasicBlock *BB,
>>> - std::vector<ValueEqualityComparisonCase> &Cases) {
>>> - for (unsigned i = 0, e = Cases.size(); i != e; ++i)
>>> - if (Cases[i].Dest == BB) {
>>> - Cases.erase(Cases.begin()+i);
>>> - --i; --e;
>>> - }
>>> -}
>>> -
>>> -/// ValuesOverlap - Return true if there are any keys in C1 that exist in C2 as
>>> -/// well.
>>> -static bool
>>> -ValuesOverlap(std::vector<ValueEqualityComparisonCase> &C1,
>>> - std::vector<ValueEqualityComparisonCase > &C2) {
>>> - std::vector<ValueEqualityComparisonCase> *V1 = &C1, *V2 = &C2;
>>> -
>>> - // Make V1 be smaller than V2.
>>> - if (V1->size() > V2->size())
>>> - std::swap(V1, V2);
>>> -
>>> - if (V1->size() == 0) return false;
>>> - if (V1->size() == 1) {
>>> - // Just scan V2.
>>> - ConstantInt *TheVal = (*V1)[0].Value;
>>> - for (unsigned i = 0, e = V2->size(); i != e; ++i)
>>> - if (TheVal == (*V2)[i].Value)
>>> - return true;
>>> - }
>>> -
>>> - // Otherwise, just sort both lists and compare element by element.
>>> - array_pod_sort(V1->begin(), V1->end());
>>> - array_pod_sort(V2->begin(), V2->end());
>>> - unsigned i1 = 0, i2 = 0, e1 = V1->size(), e2 = V2->size();
>>> - while (i1 != e1 && i2 != e2) {
>>> - if ((*V1)[i1].Value == (*V2)[i2].Value)
>>> - return true;
>>> - if ((*V1)[i1].Value < (*V2)[i2].Value)
>>> - ++i1;
>>> - else
>>> - ++i2;
>>> - }
>>> - return false;
>>> -}
>>> -
>>> /// SimplifyEqualityComparisonWithOnlyPredecessor - If TI is known to be a
>>> /// terminator instruction and its block is known to only have a single
>>> /// predecessor block, check to see if that predecessor is also a value
>>> @@ -616,23 +555,27 @@
>>> if (ThisVal != PredVal) return false; // Different predicates.
>>>
>>> // Find out information about when control will move from Pred to TI's block.
>>> - std::vector<ValueEqualityComparisonCase> PredCases;
>>> + IntegersSubsetToBB PredCases;
>>> BasicBlock *PredDef = GetValueEqualityComparisonCases(Pred->getTerminator(),
>>> PredCases);
>>> - EliminateBlockCases(PredDef, PredCases); // Remove default from cases.
>>>
>>> + // Remove default from cases.
>>> + PredCases.removeCase(PredDef);
>>> +
>>> // Find information about how control leaves this block.
>>> - std::vector<ValueEqualityComparisonCase> ThisCases;
>>> + IntegersSubsetToBB ThisCases;
>>> BasicBlock *ThisDef = GetValueEqualityComparisonCases(TI, ThisCases);
>>> - EliminateBlockCases(ThisDef, ThisCases); // Remove default from cases.
>>>
>>> + // Remove default from cases.
>>> + ThisCases.removeCase(ThisDef);
>>> +
>>> // If TI's block is the default block from Pred's comparison, potentially
>>> // simplify TI based on this knowledge.
>>> if (PredDef == TI->getParent()) {
>>> // If we are here, we know that the value is none of those cases listed in
>>> // PredCases. If there are any cases in ThisCases that are in PredCases, we
>>> // can simplify TI.
>>> - if (!ValuesOverlap(PredCases, ThisCases))
>>> + if (!PredCases.isOverlapped(ThisCases))
>>> return false;
>>>
>>> if (isa<BranchInst>(TI)) {
>>> @@ -644,7 +587,7 @@
>>> (void) NI;
>>>
>>> // Remove PHI node entries for the dead edge.
>>> - ThisCases[0].Dest->removePredecessor(TI->getParent());
>>> + ThisCases.begin()->second->removePredecessor(TI->getParent());
>>>
>>> DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
>>> << "Through successor TI: " << *TI << "Leaving: " << *NI << "\n");
>>> @@ -655,45 +598,45 @@
>>>
>>> SwitchInst *SI = cast<SwitchInst>(TI);
>>> // Okay, TI has cases that are statically dead, prune them away.
>>> - SmallPtrSet<Constant*, 16> DeadCases;
>>> - for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
>>> - DeadCases.insert(PredCases[i].Value);
>>> + IRBuilder<> CodeBuilder(SI);
>>> + CodeBuilder.SetCurrentDebugLocation(SI->getDebugLoc());
>>>
>>> DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
>>> << "Through successor TI: " << *TI);
>>>
>>> - for (SwitchInst::CaseIt i = SI->case_end(), e = SI->case_begin(); i != e;) {
>>> - --i;
>>> - if (DeadCases.count(i.getCaseValue())) {
>>> - i.getCaseSuccessor()->removePredecessor(TI->getParent());
>>> - SI->removeCase(i);
>>> - }
>>> - }
>>> -
>>> - DEBUG(dbgs() << "Leaving: " << *TI << "\n");
>>> + // Okay, TI has cases that are statically dead, prune them away.
>>> + IntegersSubsetToBB NewThisCases;
>>> + IntegersSubsetToBB WastedCases;
>>> + ThisCases.diff(&NewThisCases, &WastedCases, 0, PredCases);
>>> +
>>> + IntegersSubsetToBB::Cases Cases;
>>> + NewThisCases.getCases(Cases, true/*temporary prevent complex cases*/);
>>> +
>>> + SwitchInst *NewSI =
>>> + CodeBuilder.CreateSwitch(ThisVal, SI->getDefaultDest(), Cases.size());
>>> +
>>> + for (IntegersSubsetToBB::RangeIterator i = WastedCases.begin(),
>>> + e = WastedCases.end(); i != e; ++i)
>>> + i->second->removePredecessor(TI->getParent());
>>> +
>>> + for (IntegersSubsetToBB::CasesIt i = Cases.begin(), e = Cases.end();
>>> + i != e; ++i)
>>> + NewSI->addCase(i->second, i->first);
>>> +
>>> + EraseTerminatorInstAndDCECond(SI);
>>> + DEBUG(dbgs() << "Leaving: " << *NewSI << "\n");
>>> return true;
>>> }
>>>
>>> // Otherwise, TI's block must correspond to some matched value. Find out
>>> // which value (or set of values) this is.
>>> - ConstantInt *TIV = 0;
>>> BasicBlock *TIBB = TI->getParent();
>>> - for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
>>> - if (PredCases[i].Dest == TIBB) {
>>> - if (TIV != 0)
>>> - return false; // Cannot handle multiple values coming to this block.
>>> - TIV = PredCases[i].Value;
>>> - }
>>> - assert(TIV && "No edge from pred to succ?");
>>> + const IntItem* TIVIntITem = PredCases.getCaseSingleNumber(TIBB);
>>> + assert(TIVIntITem && "No edge from pred to succ?");
>>>
>>> // Okay, we found the one constant that our value can be if we get into TI's
>>> // BB. Find out which successor will unconditionally be branched to.
>>> - BasicBlock *TheRealDest = 0;
>>> - for (unsigned i = 0, e = ThisCases.size(); i != e; ++i)
>>> - if (ThisCases[i].Value == TIV) {
>>> - TheRealDest = ThisCases[i].Dest;
>>> - break;
>>> - }
>>> + BasicBlock *TheRealDest = ThisCases.findSuccessor(*TIVIntITem);
>>>
>>> // If not handled by any explicit cases, it is handled by the default case.
>>> if (TheRealDest == 0) TheRealDest = ThisDef;
>>> @@ -759,10 +702,10 @@
>>>
>>> if (PCV == CV && SafeToMergeTerminators(TI, PTI)) {
>>> // Figure out which 'cases' to copy from SI to PSI.
>>> - std::vector<ValueEqualityComparisonCase> BBCases;
>>> + IntegersSubsetToBB BBCases;
>>> BasicBlock *BBDefault = GetValueEqualityComparisonCases(TI, BBCases);
>>>
>>> - std::vector<ValueEqualityComparisonCase> PredCases;
>>> + IntegersSubsetToBB PredCases;
>>> BasicBlock *PredDefault = GetValueEqualityComparisonCases(PTI, PredCases);
>>>
>>> // Based on whether the default edge from PTI goes to BB or not, fill in
>>> @@ -773,61 +716,51 @@
>>> if (PredDefault == BB) {
>>> // If this is the default destination from PTI, only the edges in TI
>>> // that don't occur in PTI, or that branch to BB will be activated.
>>> - std::set<ConstantInt*, ConstantIntOrdering> PTIHandled;
>>> - for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
>>> - if (PredCases[i].Dest != BB)
>>> - PTIHandled.insert(PredCases[i].Value);
>>> - else {
>>> - // The default destination is BB, we don't need explicit targets.
>>> - std::swap(PredCases[i], PredCases.back());
>>> - PredCases.pop_back();
>>> - --i; --e;
>>> - }
>>> +
>>> + PredCases.removeCase(BB);
>>> + IntegersSubsetToBB NewBBCases;
>>> + BBCases.diff(&NewBBCases, 0, 0, PredCases);
>>> + PredCases.add(NewBBCases);
>>> + for (IntegersSubsetToBB::RangeIterator i = NewBBCases.begin(),
>>> + e = NewBBCases.end(); i != e; ++i)
>>> + NewSuccessors.push_back(i->second);
>>>
>>> - // Reconstruct the new switch statement we will be building.
>>> + // Replace the default if needed.
>>> if (PredDefault != BBDefault) {
>>> PredDefault->removePredecessor(Pred);
>>> PredDefault = BBDefault;
>>> NewSuccessors.push_back(BBDefault);
>>> }
>>> - for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
>>> - if (!PTIHandled.count(BBCases[i].Value) &&
>>> - BBCases[i].Dest != BBDefault) {
>>> - PredCases.push_back(BBCases[i]);
>>> - NewSuccessors.push_back(BBCases[i].Dest);
>>> - }
>>>
>>> } else {
>>> // If this is not the default destination from PSI, only the edges
>>> // in SI that occur in PSI with a destination of BB will be
>>> // activated.
>>> - std::set<ConstantInt*, ConstantIntOrdering> PTIHandled;
>>> - for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
>>> - if (PredCases[i].Dest == BB) {
>>> - PTIHandled.insert(PredCases[i].Value);
>>> - std::swap(PredCases[i], PredCases.back());
>>> - PredCases.pop_back();
>>> - --i; --e;
>>> - }
>>> + IntegersSubsetToBB BBPredCase;
>>> + PredCases.detachCase(BBPredCase, BB);
>>> + IntegersSubsetToBB CasesWithBBDef;
>>> + IntegersSubsetToBB InharitedCases;
>>>
>>> // Okay, now we know which constants were sent to BB from the
>>> // predecessor. Figure out where they will all go now.
>>> - for (unsigned i = 0, e = BBCases.size(); i != e; ++i)
>>> - if (PTIHandled.count(BBCases[i].Value)) {
>>> - // If this is one we are capable of getting...
>>> - PredCases.push_back(BBCases[i]);
>>> - NewSuccessors.push_back(BBCases[i].Dest);
>>> - PTIHandled.erase(BBCases[i].Value);// This constant is taken care of
>>> - }
>>> -
>>> + if (!BBPredCase.empty()) {
>>> + BBCases.diff(
>>> + 0, // LHS excl RHS
>>> + &InharitedCases, // intersection
>>> + &CasesWithBBDef, // RHS excl LHS
>>> + BBPredCase); // RHS.
>>> + }
>>> + PredCases.add(InharitedCases);
>>> + for (IntegersSubsetToBB::RangeIterator i = InharitedCases.begin(),
>>> + e = InharitedCases.end();
>>> + i != e; ++i)
>>> + NewSuccessors.push_back(i->second);
>>> +
>>> // If there are any constants vectored to BB that TI doesn't handle,
>>> // they must go to the default destination of TI.
>>> - for (std::set<ConstantInt*, ConstantIntOrdering>::iterator I =
>>> - PTIHandled.begin(),
>>> - E = PTIHandled.end(); I != E; ++I) {
>>> - PredCases.push_back(ValueEqualityComparisonCase(*I, BBDefault));
>>> + PredCases.add(CasesWithBBDef, BBDefault);
>>> + for (unsigned i = 0, e = CasesWithBBDef.size(); i != e; ++i)
>>> NewSuccessors.push_back(BBDefault);
>>> - }
>>> }
>>>
>>> // Okay, at this point, we know which new successor Pred will get. Make
>>> @@ -848,8 +781,12 @@
>>> SwitchInst *NewSI = Builder.CreateSwitch(CV, PredDefault,
>>> PredCases.size());
>>> NewSI->setDebugLoc(PTI->getDebugLoc());
>>> - for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
>>> - NewSI->addCase(PredCases[i].Value, PredCases[i].Dest);
>>> + IntegersSubsetToBB::Cases Cases;
>>> + PredCases.getCases(Cases, true/*temporary prevent complex case*/);
>>> +
>>> + for (IntegersSubsetToBB::CasesIt i = Cases.begin(), e = Cases.end();
>>> + i != e; ++i)
>>> + NewSI->addCase(i->second, i->first);
>>>
>>> EraseTerminatorInstAndDCECond(PTI);
>>>
>>>
>>> Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original)
>>> +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Jul 2 08:02:18 2012
>>> @@ -82,8 +82,8 @@
>>>
>>> ; CHECK: @test4
>>> ; CHECK: switch i8 %c, label %lor.rhs [
>>> -; CHECK: i8 62, label %lor.end
>>> ; CHECK: i8 34, label %lor.end
>>> +; CHECK: i8 62, label %lor.end
>>> ; CHECK: i8 92, label %lor.end
>>> ; CHECK: ]
>>> }
>>>
>>> Modified: llvm/trunk/unittests/Support/IntegersSubsetTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/IntegersSubsetTest.cpp?rev=159527&r1=159526&r2=159527&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/IntegersSubsetTest.cpp (original)
>>> +++ llvm/trunk/unittests/Support/IntegersSubsetTest.cpp Mon Jul 2 08:02:18 2012
>>> @@ -193,20 +193,20 @@
>>> const unsigned_ranges IntersectRes,
>>> unsigned IntersectResSize
>>> ) {
>>> -
>>> + unsigned successors[2] = {0, 1};
>>> Mapping::RangesCollection Ranges;
>>>
>>> Mapping LHSMapping;
>>> for (unsigned i = 0; i < LSize; ++i)
>>> Ranges.push_back(Range(Int(LHS[i][0]), Int(LHS[i][1])));
>>> - LHSMapping.add(Ranges);
>>> + LHSMapping.add(Ranges, &successors[0]);
>>>
>>> Ranges.clear();
>>>
>>> Mapping RHSMapping;
>>> for (unsigned i = 0; i < RSize; ++i)
>>> Ranges.push_back(Range(Int(RHS[i][0]), Int(RHS[i][1])));
>>> - RHSMapping.add(Ranges);
>>> + RHSMapping.add(Ranges, &successors[1]);
>>>
>>> Mapping LExclude, Intersection;
>>>
>>> @@ -217,8 +217,10 @@
>>>
>>> unsigned i = 0;
>>> for (Mapping::RangeIterator rei = LExclude.begin(),
>>> - e = LExclude.end(); rei != e; ++rei, ++i)
>>> + e = LExclude.end(); rei != e; ++rei, ++i) {
>>> EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
>>> + EXPECT_EQ(rei->second, &successors[0]);
>>> + }
>>> } else
>>> EXPECT_TRUE(LExclude.empty());
>>>
>>> @@ -227,8 +229,10 @@
>>>
>>> unsigned i = 0;
>>> for (Mapping::RangeIterator ii = Intersection.begin(),
>>> - e = Intersection.end(); ii != e; ++ii, ++i)
>>> + e = Intersection.end(); ii != e; ++ii, ++i) {
>>> EXPECT_EQ(ii->first, Range(IntersectRes[i][0], IntersectRes[i][1]));
>>> + EXPECT_EQ(ii->second, &successors[0]);
>>> + }
>>> } else
>>> EXPECT_TRUE(Intersection.empty());
>>>
>>> @@ -241,9 +245,11 @@
>>> EXPECT_EQ(LExclude.size(), ExcludeResSize);
>>>
>>> unsigned i = 0;
>>> - for (Mapping::RangeIterator rei = LExclude.begin(),
>>> - e = LExclude.end(); rei != e; ++rei, ++i)
>>> - EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
>>> + for (Mapping::RangeIterator lei = LExclude.begin(),
>>> + e = LExclude.end(); lei != e; ++lei, ++i) {
>>> + EXPECT_EQ(lei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1]));
>>> + EXPECT_EQ(lei->second, &successors[0]);
>>> + }
>>> } else
>>> EXPECT_TRUE(LExclude.empty());
>>> }
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>> -David
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list