aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CppBackend/CPPBackend.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-24 13:37:26 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-24 13:37:26 -0800
commite5dc5083e4c2ade01146c6e9aeba0b39ef839290 (patch)
tree39907c3d6a571472667f64ad5fdc05fbf6e3724e /lib/Target/CppBackend/CPPBackend.cpp
parent4bd6fc1f1df91829bad53502a1bb0453a6d43b61 (diff)
emit switches
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp43
1 files changed, 23 insertions, 20 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index a0ac3cf4aa..3a3b3e1c2b 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1281,25 +1281,8 @@ std::string CppWriter::generateInstruction(const Instruction *I) {
}
break;
}
- case Instruction::Br: break; // handled while relooping
- case Instruction::Switch: {
- const SwitchInst *SI = cast<SwitchInst>(I);
- Out << "SwitchInst* " << iName << " = SwitchInst::Create("
- << getOpName(SI->getCondition()) << ", "
- << getOpName(SI->getDefaultDest()) << ", "
- << SI->getNumCases() << ", " << bbname << ");";
- nl(Out);
- for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end();
- i != e; ++i) {
- const IntegersSubset CaseVal = i.getCaseValueEx();
- const BasicBlock *BB = i.getCaseSuccessor();
- Out << iName << "->addCase("
- << getOpName(CaseVal) << ", "
- << getOpName(BB) << ");";
- nl(Out);
- }
- break;
- }
+ case Instruction::Br:
+ case Instruction::Switch: break; // handled while relooping
case Instruction::IndirectBr: {
const IndirectBrInst *IBI = cast<IndirectBrInst>(I);
Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create("
@@ -2038,7 +2021,9 @@ void CppWriter::printFunctionBody(const Function *F) {
std::string curr = generateInstruction(I);
if (curr.size() > 0) contents += curr + "\n";
}
- Block *Curr = new Block(contents.c_str(), NULL); // TODO: use branch vars so we get switches
+ // TODO: if chains for small/sparse switches
+ const SwitchInst* SI = dyn_cast<SwitchInst>(BI->getTerminator());
+ Block *Curr = new Block(contents.c_str(), SI ? getValueAsCastStr(SI->getCondition()).c_str() : NULL);
const BasicBlock *BB = &*BI;
LLVMToRelooper[BB] = Curr;
R.AddBlock(Curr);
@@ -2072,6 +2057,24 @@ void CppWriter::printFunctionBody(const Function *F) {
}
break;
}
+ case Instruction::Switch: {
+ const SwitchInst* SI = cast<SwitchInst>(TI);
+ BasicBlock *DD = SI->getDefaultDest();
+ std::string P = getPhiCode(&*BI, DD);
+ LLVMToRelooper[&*BI]->AddBranchTo(LLVMToRelooper[&*DD], NULL, P.size() > 0 ? P.c_str() : NULL);
+ for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i) {
+ const BasicBlock *BB = i.getCaseSuccessor();
+ const IntegersSubset CaseVal = i.getCaseValueEx();
+ assert(CaseVal.isSingleNumbersOnly());
+ std::string Condition = "";
+ for (unsigned Index = 0; Index < CaseVal.getNumItems(); Index++) {
+ Condition += "case " + utostr(*(CaseVal.getSingleNumber(Index).toConstantInt()->getValue().getRawData())) + ':';
+ }
+ std::string P = getPhiCode(&*BI, BB);
+ LLVMToRelooper[&*BI]->AddBranchTo(LLVMToRelooper[&*BB], Condition.c_str(), P.size() > 0 ? P.c_str() : NULL);
+ }
+ break;
+ }
case Instruction::Ret:
case Instruction::Unreachable: break;
}