static bool convertFunction(Function *Func) { bool Changed = false; IntegerType *I32 = Type::getInt32Ty(Func->getContext()); // Skip zero in case programs treat a null pointer as special. uint32_t NextNum = 1; DenseMap<BasicBlock *, ConstantInt *> LabelNums; BasicBlock *DefaultBB = NULL; // Replace each indirectbr with a switch. // // If there are multiple indirectbr instructions in the function, // this could be expensive. While an indirectbr is usually // converted to O(1) machine instructions, the switch we generate // here will be O(n) in the number of target labels. // // However, Clang usually generates just a single indirectbr per // function anyway when compiling C computed gotos. // // We could try to generate one switch to handle all the indirectbr // instructions in the function, but that would be complicated to // implement given that variables that are live at one indirectbr // might not be live at others. for (llvm::Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) { if (IndirectBrInst *Br = dyn_cast<IndirectBrInst>(BB->getTerminator())) { Changed = true; if (!DefaultBB) { DefaultBB = BasicBlock::Create(Func->getContext(), "indirectbr_default", Func); new UnreachableInst(Func->getContext(), DefaultBB); } // An indirectbr can list the same target block multiple times. // Keep track of the basic blocks we've handled to avoid adding // the same case multiple times. DenseSet<BasicBlock *> BlocksSeen; Value *Cast = new PtrToIntInst(Br->getAddress(), I32, "indirectbr_cast", Br); unsigned Count = Br->getNumSuccessors(); SwitchInst *Switch = SwitchInst::Create(Cast, DefaultBB, Count, Br); for (unsigned I = 0; I < Count; ++I) { BasicBlock *Dest = Br->getSuccessor(I); if (!BlocksSeen.insert(Dest).second) { // Remove duplicated entries from phi nodes. for (BasicBlock::iterator Inst = Dest->begin(); ; ++Inst) { PHINode *Phi = dyn_cast<PHINode>(Inst); if (!Phi) break; Phi->removeIncomingValue(Br->getParent()); } continue; } ConstantInt *Val; if (LabelNums.count(Dest) == 0) { Val = ConstantInt::get(I32, NextNum++); LabelNums[Dest] = Val; BlockAddress *BA = BlockAddress::get(Func, Dest); Value *ValAsPtr = ConstantExpr::getIntToPtr(Val, BA->getType()); BA->replaceAllUsesWith(ValAsPtr); BA->destroyConstant(); } else { Val = LabelNums[Dest]; } Switch->addCase(Val, Br->getSuccessor(I)); } Br->eraseFromParent(); } } // If there are any blockaddresses that are never used by an // indirectbr, replace them with dummy values. SmallVector<Value *, 20> Uses(Func->use_begin(), Func->use_end()); for (SmallVectorImpl<Value *>::iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) { if (BlockAddress *BA = dyn_cast<BlockAddress>(*UI)) { Changed = true; Value *DummyVal = ConstantExpr::getIntToPtr(ConstantInt::get(I32, ~0L), BA->getType()); BA->replaceAllUsesWith(DummyVal); BA->destroyConstant(); } } return Changed; }