#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONSPECIALIZE_H
#define LLVM_TRANSFORMS_IPO_FUNCTIONSPECIALIZE_H

#include "llvm/IR/PassManager.h"
#include <set>
#include <map>

namespace llvm {
namespace aocc {
using namespace llvm;

class FunctionSpecializePass
  :public PassInfoMixin<FunctionSpecializePass> {
public:
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};

} // namespace aocc

typedef std::set<CallInst *> CallSet;
typedef std::map<Function *, CallSet> CallsMap;
struct FunctionSpecializeAction {
  /* New function created by refactoring the logic in transforms fun
   Use to populate Callsite for which specialization need to done.*/
  CallsMap selectCI(Module &M, bool IsInlineSpecial = false);
  bool transform(Module &M, CallsMap &Calls,
                 const std::set<CallInst *> &GCPEligibleCallSites =
                     std::set<CallInst *>() /*default for legacy PM*/);
  bool isRecurFnWithAOPInput(Function *Fn);
  bool isFuncDirectRecursive(Function *Fn);
};
} // namespace llvm

#endif
