Commit 19e6eec2 by Nicolas Capens

Implement Else without using basic block predecessor.

Bug swiftshader:13 Change-Id: Idd49e64aa8415ceb5d1cfee7b65a7d67ea0ebd40 Reviewed-on: https://swiftshader-review.googlesource.com/7792Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent f981c2d2
...@@ -69,6 +69,8 @@ namespace ...@@ -69,6 +69,8 @@ namespace
llvm::Function *function = nullptr; llvm::Function *function = nullptr;
sw::BackoffLock codegenMutex; sw::BackoffLock codegenMutex;
sw::BasicBlock *falseBB = nullptr;
} }
namespace sw namespace sw
...@@ -286,11 +288,6 @@ namespace sw ...@@ -286,11 +288,6 @@ namespace sw
return ::builder->SetInsertPoint(basicBlock); return ::builder->SetInsertPoint(basicBlock);
} }
BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
{
return B(*pred_begin(basicBlock));
}
void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params) void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
{ {
llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false); llvm::FunctionType *functionType = llvm::FunctionType::get(ReturnType, T(Params), false);
...@@ -6739,14 +6736,28 @@ namespace sw ...@@ -6739,14 +6736,28 @@ namespace sw
return true; return true;
} }
void endIf(BasicBlock *falseBB)
{
::falseBB = falseBB;
}
bool elseBlock(BasicBlock *falseBB) bool elseBlock(BasicBlock *falseBB)
{ {
assert(falseBB && "Else not preceded by If");
falseBB->back().eraseFromParent(); falseBB->back().eraseFromParent();
Nucleus::setInsertBlock(falseBB); Nucleus::setInsertBlock(falseBB);
return true; return true;
} }
BasicBlock *beginElse()
{
BasicBlock *falseBB = ::falseBB;
::falseBB = nullptr;
return falseBB;
}
RValue<Long> Ticks() RValue<Long> Ticks()
{ {
llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter); llvm::Function *rdtsc = Intrinsic::getDeclaration(::module, Intrinsic::readcyclecounter);
......
...@@ -258,6 +258,64 @@ TEST(SubzeroReactorTest, Swizzle) ...@@ -258,6 +258,64 @@ TEST(SubzeroReactorTest, Swizzle)
delete routine; delete routine;
} }
TEST(SubzeroReactorTest, Branching)
{
Routine *routine = nullptr;
{
Function<Int(Void)> function;
{
Int x = 0;
For(Int i = 0, i < 8, i++)
{
If(i < 2)
{
x += 1;
}
Else If(i < 4)
{
x += 10;
}
Else If(i < 6)
{
x += 100;
}
Else
{
x += 1000;
}
For(Int i = 0, i < 5, i++)
x += 10000;
}
For(Int j = 0, j < 2, j++)
If(x == 402222)
{
If(x != 402222)
x += 1000000;
}
Else
x = -5;
Return(x);
}
routine = function(L"one");
if(routine)
{
int(*callable)() = (int(*)())routine->getEntry();
int result = callable();
EXPECT_EQ(result, 402222);
}
}
delete routine;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
......
...@@ -57,7 +57,6 @@ namespace sw ...@@ -57,7 +57,6 @@ namespace sw
static BasicBlock *createBasicBlock(); static BasicBlock *createBasicBlock();
static BasicBlock *getInsertBlock(); static BasicBlock *getInsertBlock();
static void setInsertBlock(BasicBlock *basicBlock); static void setInsertBlock(BasicBlock *basicBlock);
static BasicBlock *getPredecessor(BasicBlock *basicBlock);
static void createFunction(Type *ReturnType, std::vector<Type*> &Params); static void createFunction(Type *ReturnType, std::vector<Type*> &Params);
static Value *getArgument(unsigned int index); static Value *getArgument(unsigned int index);
......
...@@ -2227,7 +2227,9 @@ namespace sw ...@@ -2227,7 +2227,9 @@ namespace sw
BasicBlock *beginLoop(); BasicBlock *beginLoop();
bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB); bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
void endIf(BasicBlock *falseBB);
bool elseBlock(BasicBlock *falseBB); bool elseBlock(BasicBlock *falseBB);
BasicBlock *beginElse();
void Return(); void Return();
void Return(bool ret); void Return(bool ret);
...@@ -2840,18 +2842,25 @@ namespace sw ...@@ -2840,18 +2842,25 @@ namespace sw
#define If(cond) \ #define If(cond) \
for(BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \ for(BasicBlock *trueBB__ = Nucleus::createBasicBlock(), \
*falseBB__ = Nucleus::createBasicBlock(), \ *falseBB__ = Nucleus::createBasicBlock(), \
*endBB__ = Nucleus::createBasicBlock(), \ *endBB__ = Nucleus::createBasicBlock(), \
*onceBB__ = endBB__; \ *onceBB__ = endBB__; \
onceBB__ && branch(cond, trueBB__, falseBB__); \ onceBB__ && branch(cond, trueBB__, falseBB__); \
onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(falseBB__), Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__)) onceBB__ = nullptr, \
Nucleus::createBr(endBB__), \
Nucleus::setInsertBlock(falseBB__), \
Nucleus::createBr(endBB__), \
Nucleus::setInsertBlock(endBB__), \
endIf(falseBB__))
#define Else \ #define Else \
for(BasicBlock *endBB__ = Nucleus::getInsertBlock(), \ for(BasicBlock *elseBB__ = beginElse(), \
*falseBB__ = Nucleus::getPredecessor(endBB__), \ *endBB__ = Nucleus::getInsertBlock(), \
*onceBB__ = endBB__; \ *onceBB__ = endBB__; \
onceBB__ && elseBlock(falseBB__); \ onceBB__ && elseBlock(elseBB__); \
onceBB__ = 0, Nucleus::createBr(endBB__), Nucleus::setInsertBlock(endBB__)) onceBB__ = nullptr, \
Nucleus::createBr(endBB__), \
Nucleus::setInsertBlock(endBB__))
} }
#endif // sw_Reactor_hpp #endif // sw_Reactor_hpp
...@@ -47,6 +47,8 @@ namespace ...@@ -47,6 +47,8 @@ namespace
std::mutex codegenMutex; std::mutex codegenMutex;
sw::BasicBlock *falseBB = nullptr;
Ice::ELFFileStreamer *elfFile = nullptr; Ice::ELFFileStreamer *elfFile = nullptr;
Ice::Fdstream *out = nullptr; Ice::Fdstream *out = nullptr;
} }
...@@ -471,15 +473,10 @@ namespace sw ...@@ -471,15 +473,10 @@ namespace sw
void Nucleus::setInsertBlock(BasicBlock *basicBlock) void Nucleus::setInsertBlock(BasicBlock *basicBlock)
{ {
assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator"); // assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
::basicBlock = basicBlock; ::basicBlock = basicBlock;
} }
BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
{
assert(false && "UNIMPLEMENTED"); return nullptr;
}
void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params) void Nucleus::createFunction(Type *ReturnType, std::vector<Type*> &Params)
{ {
uint32_t sequenceNumber = 0; uint32_t sequenceNumber = 0;
...@@ -6168,13 +6165,28 @@ namespace sw ...@@ -6168,13 +6165,28 @@ namespace sw
return true; return true;
} }
void endIf(BasicBlock *falseBB)
{
::falseBB = falseBB;
}
bool elseBlock(BasicBlock *falseBB) bool elseBlock(BasicBlock *falseBB)
{ {
assert(falseBB && "Else not preceded by If");
falseBB->getInsts().back().setDeleted();
Nucleus::setInsertBlock(falseBB); Nucleus::setInsertBlock(falseBB);
return true; return true;
} }
BasicBlock *beginElse()
{
BasicBlock *falseBB = ::falseBB;
::falseBB = nullptr;
return falseBB;
}
RValue<Long> Ticks() RValue<Long> Ticks()
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr)); assert(false && "UNIMPLEMENTED"); return RValue<Long>(V(nullptr));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment