- // Create a new basic block to copy instructions into!
- BasicBlock *IBB = new BasicBlock("", NewBB->getParent());
- if (BB->hasName()) IBB->setName(BB->getName()+".i"); // .i = inlined once
-
- ValueMap[BB] = IBB; // Add basic block mapping.
-
- // Make sure to capture the mapping that a return will use...
- // TODO: This assumes that the RET is returning a value computed in the same
- // basic block as the return was issued from!
- //
- const TerminatorInst *TI = BB->getTerminator();
-
- // Loop over all instructions copying them over...
- Instruction *NewInst;
- for (BasicBlock::const_iterator II = BB->begin();
- II != --BB->end(); ++II) {
- IBB->getInstList().push_back((NewInst = II->clone()));
- ValueMap[II] = NewInst; // Add instruction map to value.
- if (II->hasName())
- NewInst->setName(II->getName()+".i"); // .i = inlined once
- }
-
- // Copy over the terminator now...
- switch (TI->getOpcode()) {
- case Instruction::Ret: {
- const ReturnInst *RI = cast<ReturnInst>(TI);
-
- if (PHI) { // The PHI node should include this value!
- assert(RI->getReturnValue() && "Ret should have value!");
- assert(RI->getReturnValue()->getType() == PHI->getType() &&
- "Ret value not consistent in function!");
- PHI->addIncoming((Value*)RI->getReturnValue(),
- (BasicBlock*)cast<BasicBlock>(&*BB));
- }
-
- // Add a branch to the code that was after the original Call.
- IBB->getInstList().push_back(new BranchInst(NewBB));
- break;
- }
- case Instruction::Br:
- IBB->getInstList().push_back(TI->clone());
- break;
-
- default:
- cerr << "FunctionInlining: Don't know how to handle terminator: " << TI;
- abort();
- }
- }
-
-
- // Loop over all of the instructions in the function, fixing up operand
- // references as we go. This uses ValueMap to do all the hard work.
- //
- for (Function::const_iterator BB = CalledFunc->begin();
- BB != CalledFunc->end(); ++BB) {
- BasicBlock *NBB = (BasicBlock*)ValueMap[BB];
-
- // Loop over all instructions, fixing each one as we find it...
- //
- for (BasicBlock::iterator II = NBB->begin(); II != NBB->end(); ++II)
- RemapInstruction(II, ValueMap);
- }
-
- if (PHI) RemapInstruction(PHI, ValueMap); // Fix the PHI node also...
-
- // Change the branch that used to go to NewBB to branch to the first basic
- // block of the inlined function.
- //
- TerminatorInst *Br = OrigBB->getTerminator();
- assert(Br && Br->getOpcode() == Instruction::Br &&
- "splitBasicBlock broken!");
- Br->setOperand(0, ValueMap[&CalledFunc->front()]);
-
- // Since we are now done with the CallInst, we can finally delete it.
- delete CI;
- return true;
-}
-
-static inline bool ShouldInlineFunction(const CallInst *CI, const Function *F) {
- assert(CI->getParent() && CI->getParent()->getParent() &&
- "Call not embedded into a function!");
-
- // Don't inline a recursive call.
- if (CI->getParent()->getParent() == F) return false;
-
- // Don't inline something too big. This is a really crappy heuristic
- if (F->size() > 3) return false;
-
- // Don't inline into something too big. This is a **really** crappy heuristic
- if (CI->getParent()->getParent()->size() > 10) return false;
-
- // Go ahead and try just about anything else.
- return true;
-}
-
-
-static inline bool DoFunctionInlining(BasicBlock *BB) {
- for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
- if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
- // Check to see if we should inline this function
- Function *F = CI->getCalledFunction();
- if (F && ShouldInlineFunction(CI, F)) {
- return InlineFunction(CI);
- }
- }