Eliminate "false" basic block when no Else clause.
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>
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index f0dcced..5dda0d2 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -2226,129 +2226,6 @@
// 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 @@
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 @@
Nucleus::setInsertBlock(end__); \
}
- #define If(cond) \
- for(IfData if__ = cond; if__; if__ = false)
+ enum {IF_BLOCK__, ELSE_CLAUSE__, ELSE_BLOCK__, IFELSE_NUM__};
- #define Else \
- for(ElseData else__ = true; else__; else__ = false)
+ #define If(cond) \
+ for(IfElseData ifElse__(cond); ifElse__ < IFELSE_NUM__; ++ifElse__) \
+ if(ifElse__ == IF_BLOCK__)
+
+ #define Else \
+ else if(ifElse__ == ELSE_CLAUSE__) \
+ { \
+ ifElse__.elseClause(); \
+ } \
+ else // ELSE_BLOCK__
}
#endif // sw_Reactor_hpp