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>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 706d1f9..247c95f 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -69,8 +69,6 @@
 	llvm::Function *function = nullptr;
 
 	sw::BackoffLock codegenMutex;
-
-	sw::BasicBlock *falseBB = nullptr;
 }
 
 namespace sw
@@ -6717,28 +6715,6 @@
 		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);
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index f0dcced..b85eeca 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,16 @@
 		Nucleus::setInsertBlock(end__);                     \
 	}
 
-	#define If(cond) \
-	for(IfData if__ = cond; if__; if__ = false)
+	#define If(cond)                                         \
+	for(IfElseData ifElse__(cond); ifElse__ < 3; ++ifElse__) \
+	if(ifElse__ == 0)
 
-	#define Else \
-	for(ElseData else__ = true; else__; else__ = false)
+	#define Else                \
+	else if(ifElse__ == 1)      \
+	{                           \
+		 ifElse__.elseClause(); \
+	}                           \
+	else
 }
 
 #endif   // sw_Reactor_hpp
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 76ac3ae..db2294a 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -47,8 +47,6 @@
 
 	std::mutex codegenMutex;
 
-	sw::BasicBlock *falseBB = nullptr;
-
 	Ice::ELFFileStreamer *elfFile = nullptr;
 	Ice::Fdstream *out = nullptr;
 }
@@ -6531,31 +6529,8 @@
 		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));
 	}
 }
-