#ifndef LLVM_ANALYSIS_HIERARCHICALTYPE_H
#define LLVM_ANALYSIS_HIERARCHICALTYPE_H

#include "llvm/IR/PassManager.h"
#include "llvm/Analysis/CallSiteAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TBAATypeReconstruction.h"
#include "llvm/Transforms/Utils/CodeMoverUtils.h"

#include <stack>

namespace llvm {
typedef std::vector<TBAATypeReconstruction::TypeInfo*> HierachicalType;
bool areLockstepEquivalent(Value* A, Value* B, Module &M, TBAATypeReconstruction &TypeRecon, aocc::CSFunctionProperty &CS, FunctionAnalysisManager &FAM, std::optional<ControlConditionVector> Predicates);
std::optional<std::set<Instruction*>> getMemAffInsts(HierachicalType HierType,
  Module &M, TBAATypeReconstruction &TypeRecon, aocc::CSFunctionProperty &CS,
  FunctionAnalysisManager &FAM);
std::optional<std::set<Function*>> getCalledFunctions(CallBase *Call, aocc::CSFunctionProperty &CS);
std::optional<Value*> getValueFromSCEV(const SCEV* S);
std::optional<std::stack<Value*>> getLoadChain(Value* Op, int MaxLoadDepth);
Value* getUniqueValue(PHINode *PhiNode);
} // namespace llvm

#endif // LLVM_ANALYSIS_HIERARCHICALTYPE_H
