//===- SimplifyHalfPowrLibCalls.cpp - Optimize specific half_powr calls ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a simple pass that applies an experimental
// transformation on calls to specific functions.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "simplify-libcalls-halfpowr"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
using namespace llvm;

namespace {
  /// This pass optimizes well half_powr function calls.
  ///
  class SimplifyHalfPowrLibCalls : public FunctionPass {
    const TargetData *TD;
  public:
    static char ID; // Pass identification
    SimplifyHalfPowrLibCalls() : FunctionPass(ID) {}

    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    }

    Instruction *
    InlineHalfPowrs(const std::vector<Instruction *> &HalfPowrs,
                    Instruction *InsertPt);
  };
  char SimplifyHalfPowrLibCalls::ID = 0;
} // end anonymous namespace.

INITIALIZE_PASS(SimplifyHalfPowrLibCalls, "simplify-libcalls-halfpowr",
                "Simplify half_powr library calls", false, false);

// Public interface to the Simplify HalfPowr LibCalls pass.
FunctionPass *llvm::createSimplifyHalfPowrLibCallsPass() {
  return new SimplifyHalfPowrLibCalls(); 
}

/// InlineHalfPowrs - Inline a sequence of adjacent half_powr calls, rearranging
/// their control flow to better facilitate subsequent optimization.
Instruction *
SimplifyHalfPowrLibCalls::
InlineHalfPowrs(const std::vector<Instruction *> &HalfPowrs,
                Instruction *InsertPt) {
  std::vector<BasicBlock *> Bodies;
  BasicBlock *NewBlock = 0;

  for (unsigned i = 0, e = HalfPowrs.size(); i != e; ++i) {
    CallInst *Call = cast<CallInst>(HalfPowrs[i]);
    Function *Callee = Call->getCalledFunction();

    // Minimally sanity-check the CFG of half_powr to ensure that it contains
    // the kind of code we expect.  If we're running this pass, we have
    // reason to believe it will be what we expect.
    Function::iterator I = Callee->begin();
    BasicBlock *Prologue = I++;
    if (I == Callee->end()) break;
    BasicBlock *SubnormalHandling = I++;
    if (I == Callee->end()) break;
    BasicBlock *Body = I++;
    if (I != Callee->end()) break;
    if (SubnormalHandling->getSinglePredecessor() != Prologue)
      break;
    BranchInst *PBI = dyn_cast<BranchInst>(Prologue->getTerminator());
    if (!PBI || !PBI->isConditional())
      break;
    BranchInst *SNBI = dyn_cast<BranchInst>(SubnormalHandling->getTerminator());
    if (!SNBI || SNBI->isConditional())
      break;
    if (!isa<ReturnInst>(Body->getTerminator()))
      break;

    Instruction *NextInst = llvm::next(BasicBlock::iterator(Call));

    // Inline the call, taking care of what code ends up where.
    NewBlock = SplitBlock(NextInst->getParent(), NextInst, this);

    InlineFunctionInfo IFI(0, TD);
    bool B = InlineFunction(Call, IFI);
    assert(B && "half_powr didn't inline?"); B=B;

    BasicBlock *NewBody = NewBlock->getSinglePredecessor();
    assert(NewBody);
    Bodies.push_back(NewBody);
  }

  if (!NewBlock)
    return InsertPt;

  // Put the code for all the bodies into one block, to facilitate
  // subsequent optimization.
  (void)SplitEdge(NewBlock->getSinglePredecessor(), NewBlock, this);
  for (unsigned i = 0, e = Bodies.size(); i != e; ++i) {
    BasicBlock *Body = Bodies[i];
    Instruction *FNP = Body->getFirstNonPHI();
    // Splice the insts from body into NewBlock.
    NewBlock->getInstList().splice(NewBlock->begin(), Body->getInstList(),
                                   FNP, Body->getTerminator());
  }

  return NewBlock->begin();
}

/// runOnFunction - Top level algorithm.
///
bool SimplifyHalfPowrLibCalls::runOnFunction(Function &F) {
  TD = getAnalysisIfAvailable<TargetData>();
  
  bool Changed = false;
  std::vector<Instruction *> HalfPowrs;
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
      // Look for calls.
      bool IsHalfPowr = false;
      if (CallInst *CI = dyn_cast<CallInst>(I)) {
        // Look for direct calls and calls to non-external functions.
        Function *Callee = CI->getCalledFunction();
        if (Callee && Callee->hasExternalLinkage()) {
          // Look for calls with well-known names.
          if (Callee->getName() == "__half_powrf4")
            IsHalfPowr = true;
        }
      }
      if (IsHalfPowr)
        HalfPowrs.push_back(I);
      // We're looking for sequences of up to three such calls, which we'll
      // simplify as a group.
      if ((!IsHalfPowr && !HalfPowrs.empty()) || HalfPowrs.size() == 3) {
        I = InlineHalfPowrs(HalfPowrs, I);
        E = I->getParent()->end();
        HalfPowrs.clear();
        Changed = true;
      }
    }
    assert(HalfPowrs.empty() && "Block had no terminator!");
  }

  return Changed;
}
