#ifndef INCLUDE_UNIT_LOOP_INFO_H
#define INCLUDE_UNIT_LOOP_INFO_H
#include <vector>
#include <memory>
#include "llvm/IR/PassManager.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
namespace llvm {
class Value;
class Instruction;
class BasicBlock;
class DominatorTree;
class LoadInst;
class StoreInst;
}
using namespace llvm;
namespace ece479k {
struct UnitLoopInfo {
private:
// The basic blocks that form this loop
SmallPtrSet<BasicBlock*, 16> set;
// The blocks in *reverse* order
SmallVector<BasicBlock*, 16> blocks;
public:
BasicBlock const* header;
BasicBlock const* preheader;
SmallPtrSet<BasicBlock const*, 4> exits;
private:
std::unique_ptr<AliasSetTracker> alias_sets;
public:
using alias_results = AAResults&;
// Record a natural loop given its backedge from end to header
UnitLoopInfo(BasicBlock* header, BasicBlock* end, alias_results AA, DominatorTree& DT);
/*loop properties*/
[[nodiscard]] bool contains(BasicBlock const*) const;
[[nodiscard]] bool contains(BasicBlock const&) const;
[[nodiscard]] bool contains(Instruction const*) const;
[[nodiscard]] bool contains(Instruction const&) const;
[[nodiscard]] bool contains(Value const*) const;
[[nodiscard]] bool contains(Value const&) const;
/*loop invariants*/
[[nodiscard]] bool is_invariant(Value const*) const;
[[nodiscard]] bool is_invariant(Value const&) const;
[[nodiscard]] bool is_invariant(Instruction const*) const;
[[nodiscard]] bool is_invariant(Instruction const&) const;
[[nodiscard]] bool has_invariant_operands(Instruction const*) const;
[[nodiscard]] bool has_invariant_operands(Instruction const&) const;
/*utility*/
[[nodiscard]] std::vector<Instruction*> instructions() const;
[[nodiscard]] std::vector<Instruction*> instructions(std::function<bool(Instruction const&)> const&) const;
[[nodiscard]] AliasSet const& alias_for(LoadInst const*) const;
[[nodiscard]] AliasSet const& alias_for(StoreInst const*) const;
};
/// Loop Identification Analysis Pass. Produces a UnitLoopInfo object which
/// should contain any information about the loops in the function which is
/// needed for your implementation of LICM
class UnitLoopAnalysis : public AnalysisInfoMixin<UnitLoopAnalysis> {
friend AnalysisInfoMixin<UnitLoopAnalysis>;
static AnalysisKey Key;
public:
using Result = std::vector<UnitLoopInfo>;
Result run(Function &F, FunctionAnalysisManager &AM);
};
} // namespace ece479k
#endif // INCLUDE_UNIT_LOOP_INFO_H