diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-11-24 13:37:26 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-11-24 13:37:26 -0800 |
commit | e5dc5083e4c2ade01146c6e9aeba0b39ef839290 (patch) | |
tree | 39907c3d6a571472667f64ad5fdc05fbf6e3724e /lib/Target/CppBackend/CPPBackend.cpp | |
parent | 4bd6fc1f1df91829bad53502a1bb0453a6d43b61 (diff) |
emit switches
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 43 |
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; } |