OSDN Git Service

Eliminate "false" basic block when no Else clause.
authorNicolas Capens <capn@google.com>
Wed, 16 Nov 2016 22:40:48 +0000 (17:40 -0500)
committerNicolas Capens <capn@google.com>
Fri, 2 Dec 2016 17:29:44 +0000 (17:29 +0000)
Bug swiftshader:13

Change-Id: I5dd2ce4ddf1eaf0ec2fc732d022ccad2331e6b6b
Reviewed-on: https://swiftshader-review.googlesource.com/8070
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-on: https://swiftshader-review.googlesource.com/8230
Reviewed-by: Alexis Hétu <sugoi@google.com>
src/Reactor/LLVMReactor.cpp
src/Reactor/Reactor.hpp
src/Reactor/SubzeroReactor.cpp

index 66e330d..811edab 100644 (file)
@@ -69,8 +69,6 @@ namespace
        llvm::Function *function = nullptr;
 
        sw::BackoffLock codegenMutex;
-
-       sw::BasicBlock *falseBB = nullptr;
 }
 
 namespace sw
@@ -6717,28 +6715,6 @@ namespace sw
                return true;
        }
 
-       void endIf(BasicBlock *falseBB)
-       {
-               ::falseBB = falseBB;
-       }
-
-       bool elseBlock(BasicBlock *falseBB)
-       {
-               assert(falseBB && "Else not preceded by If");
-               falseBB->back().eraseFromParent();
-               Nucleus::setInsertBlock(falseBB);
-
-               return true;
-       }
-
-       BasicBlock *beginElse()
-       {
-               BasicBlock *falseBB = ::falseBB;
-               ::falseBB = nullptr;
-
-               return falseBB;
-       }
-
        RValue<Long> Ticks()
        {
                llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
index f0dcced..5dda0d2 100644 (file)
@@ -2226,129 +2226,6 @@ namespace sw
 //     const Array<T> &operator--(const Array<T> &val);   // Pre-decrement
 
        bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
-       void endIf(BasicBlock *falseBB);
-       bool elseBlock(BasicBlock *falseBB);
-       BasicBlock *beginElse();
-
-       class ForData
-       {
-       public:
-               ForData(bool init) : loopOnce(init)
-               {
-               }
-
-               operator bool()
-               {
-                       return loopOnce;
-               }
-
-               bool operator=(bool value)
-               {
-                       return loopOnce = value;
-               }
-
-               bool setup()
-               {
-                       if(Nucleus::getInsertBlock() != endBB)
-                       {
-                               testBB = Nucleus::createBasicBlock();
-
-                               Nucleus::createBr(testBB);
-                               Nucleus::setInsertBlock(testBB);
-
-                               return true;
-                       }
-
-                       return false;
-               }
-
-               bool test(RValue<Bool> cmp)
-               {
-                       BasicBlock *bodyBB = Nucleus::createBasicBlock();
-                       endBB = Nucleus::createBasicBlock();
-
-                       Nucleus::createCondBr(cmp.value, bodyBB, endBB);
-                       Nucleus::setInsertBlock(bodyBB);
-
-                       return true;
-               }
-
-               void end()
-               {
-                       Nucleus::createBr(testBB);
-                       Nucleus::setInsertBlock(endBB);
-               }
-
-       private:
-               BasicBlock *testBB = nullptr;
-               BasicBlock *endBB = nullptr;
-               bool loopOnce = true;
-       };
-
-       class IfData
-       {
-       public:
-               IfData(RValue<Bool> cmp) : loopOnce(true)
-               {
-                       trueBB = Nucleus::createBasicBlock();
-                       falseBB = Nucleus::createBasicBlock();
-                       endBB = Nucleus::createBasicBlock();
-
-                       branch(cmp, trueBB, falseBB);
-               }
-
-               operator bool()
-               {
-                       return loopOnce;
-               }
-
-               bool operator=(bool value)
-               {
-                       Nucleus::createBr(endBB);
-                       Nucleus::setInsertBlock(falseBB);
-                       Nucleus::createBr(endBB);
-                       Nucleus::setInsertBlock(endBB);
-                       endIf(falseBB);
-
-                       return loopOnce = value;
-               }
-
-       private:
-               BasicBlock *trueBB;
-               BasicBlock *falseBB;
-               BasicBlock *endBB;
-               bool loopOnce;
-       };
-
-       class ElseData
-       {
-       public:
-               ElseData(bool init) : loopOnce(init)
-               {
-                       elseBB = beginElse();
-                       endBB = Nucleus::getInsertBlock();
-
-                       elseBlock(elseBB);
-               }
-
-               operator bool()
-               {
-                       return loopOnce;
-               }
-
-               bool operator=(bool value)
-               {
-                       Nucleus::createBr(endBB);
-                       Nucleus::setInsertBlock(endBB);
-
-                       return loopOnce = value;
-               }
-
-       private:
-               BasicBlock *elseBB;
-               BasicBlock *endBB;
-               bool loopOnce;
-       };
 
        void Return();
        void Return(bool ret);
@@ -2942,6 +2819,115 @@ namespace sw
                return ReinterpretCast<T>(val);
        }
 
+       class ForData
+       {
+       public:
+               ForData(bool init) : loopOnce(init)
+               {
+               }
+
+               operator bool()
+               {
+                       return loopOnce;
+               }
+
+               bool operator=(bool value)
+               {
+                       return loopOnce = value;
+               }
+
+               bool setup()
+               {
+                       if(Nucleus::getInsertBlock() != endBB)
+                       {
+                               testBB = Nucleus::createBasicBlock();
+
+                               Nucleus::createBr(testBB);
+                               Nucleus::setInsertBlock(testBB);
+
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               bool test(RValue<Bool> cmp)
+               {
+                       BasicBlock *bodyBB = Nucleus::createBasicBlock();
+                       endBB = Nucleus::createBasicBlock();
+
+                       Nucleus::createCondBr(cmp.value, bodyBB, endBB);
+                       Nucleus::setInsertBlock(bodyBB);
+
+                       return true;
+               }
+
+               void end()
+               {
+                       Nucleus::createBr(testBB);
+                       Nucleus::setInsertBlock(endBB);
+               }
+
+       private:
+               BasicBlock *testBB = nullptr;
+               BasicBlock *endBB = nullptr;
+               bool loopOnce = true;
+       };
+
+       class IfElseData
+       {
+       public:
+               IfElseData(RValue<Bool> cmp) : iteration(0)
+               {
+                       condition = cmp.value;
+
+                       beginBB = Nucleus::getInsertBlock();
+                       trueBB = Nucleus::createBasicBlock();
+                       falseBB = nullptr;
+                       endBB = Nucleus::createBasicBlock();
+
+                       Nucleus::setInsertBlock(trueBB);
+               }
+
+               ~IfElseData()
+               {
+                       Nucleus::createBr(endBB);
+
+                       Nucleus::setInsertBlock(beginBB);
+                       Nucleus::createCondBr(condition, trueBB, falseBB ? falseBB : endBB);
+
+                       Nucleus::setInsertBlock(endBB);
+               }
+
+               operator int()
+               {
+                       return iteration;
+               }
+
+               IfElseData &operator++()
+               {
+                       ++iteration;
+
+                       return *this;
+               }
+
+               void elseClause()
+               {
+                       Nucleus::createBr(endBB);
+
+                       falseBB = Nucleus::createBasicBlock();
+                       Nucleus::setInsertBlock(falseBB);
+               }
+
+       private:
+               Value *condition;
+               BasicBlock *beginBB;
+               BasicBlock *trueBB;
+               BasicBlock *falseBB;
+               BasicBlock *endBB;
+               int iteration;
+       };
+
        #define For(init, cond, inc) \
        for(ForData for__ = true; for__; for__ = false) \
        for(init; for__.setup() && for__.test(cond); inc, for__.end())
@@ -2960,11 +2946,18 @@ namespace sw
                Nucleus::setInsertBlock(end__);                     \
        }
 
-       #define If(cond) \
-       for(IfData if__ = cond; if__; if__ = false)
+       enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__};
+
+       #define If(cond)                                                    \
+       for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
+       if(ifElse__ == IF_BLOCK__)
 
-       #define Else \
-       for(ElseData else__ = true; else__; else__ = false)
+       #define Else                       \
+       else if(ifElse__ == ELSE_CLAUSE__) \
+       {                                  \
+                ifElse__.elseClause();        \
+       }                                  \
+       else   // ELSE_BLOCK__
 }
 
 #endif   // sw_Reactor_hpp
index 76ac3ae..db2294a 100644 (file)
@@ -47,8 +47,6 @@ namespace
 
        std::mutex codegenMutex;
 
-       sw::BasicBlock *falseBB = nullptr;
-
        Ice::ELFFileStreamer *elfFile = nullptr;
        Ice::Fdstream *out = nullptr;
 }
@@ -6531,31 +6529,8 @@ namespace sw
                return true;
        }
 
-       void endIf(BasicBlock *falseBB)
-       {
-               ::falseBB = falseBB;
-       }
-
-       bool elseBlock(BasicBlock *falseBB)
-       {
-               assert(falseBB && "Else not preceded by If");
-               falseBB->getInsts().back().setDeleted();
-               Nucleus::setInsertBlock(falseBB);
-
-               return true;
-       }
-
-       BasicBlock *beginElse()
-       {
-               BasicBlock *falseBB = ::falseBB;
-               ::falseBB = nullptr;
-
-               return falseBB;
-       }
-
        RValue<Long> Ticks()
        {
                assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
        }
 }
-