#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
#define LLVM_CODEGEN_MACHINEFUNCTION_H
#include "llvm/ADT/ilist.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Recycler.h"
namespace llvm {
class Value;
class Function;
class GCModuleInfo;
class MachineRegisterInfo;
class MachineFrameInfo;
class MachineConstantPool;
class MachineJumpTableInfo;
class MachineModuleInfo;
class MCContext;
class Pass;
class PseudoSourceValueManager;
class TargetMachine;
class TargetSubtargetInfo;
class TargetRegisterClass;
struct MachinePointerInfo;
struct WinEHFuncInfo;
template <>
struct ilist_traits<MachineBasicBlock>
: public ilist_default_traits<MachineBasicBlock> {
mutable ilist_half_node<MachineBasicBlock> Sentinel;
public:
LLVM_NO_SANITIZE("object-size")
MachineBasicBlock *createSentinel() const {
return static_cast<MachineBasicBlock*>(&Sentinel);
}
void destroySentinel(MachineBasicBlock *) const {}
MachineBasicBlock *provideInitialHead() const { return createSentinel(); }
MachineBasicBlock *ensureHead(MachineBasicBlock*) const {
return createSentinel();
}
static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {}
void addNodeToList(MachineBasicBlock* MBB);
void removeNodeFromList(MachineBasicBlock* MBB);
void deleteNode(MachineBasicBlock *MBB);
private:
void createNode(const MachineBasicBlock &);
};
struct MachineFunctionInfo {
virtual ~MachineFunctionInfo();
template<typename Ty>
static Ty *create(BumpPtrAllocator &Allocator, MachineFunction &MF) {
return new (Allocator.Allocate<Ty>()) Ty(MF);
}
};
class MachineFunction {
const Function *Fn;
const TargetMachine &Target;
const TargetSubtargetInfo *STI;
MCContext &Ctx;
MachineModuleInfo &MMI;
MachineRegisterInfo *RegInfo;
MachineFunctionInfo *MFInfo;
MachineFrameInfo *FrameInfo;
MachineConstantPool *ConstantPool;
MachineJumpTableInfo *JumpTableInfo;
WinEHFuncInfo *WinEHInfo = nullptr;
std::vector<MachineBasicBlock*> MBBNumbering;
BumpPtrAllocator Allocator;
Recycler<MachineInstr> InstructionRecycler;
ArrayRecycler<MachineOperand> OperandRecycler;
Recycler<MachineBasicBlock> BasicBlockRecycler;
typedef ilist<MachineBasicBlock> BasicBlockListType;
BasicBlockListType BasicBlocks;
unsigned FunctionNumber;
unsigned Alignment;
bool ExposesReturnsTwice = false;
bool HasInlineAsm = false;
std::unique_ptr<PseudoSourceValueManager> PSVManager;
MachineFunction(const MachineFunction &) = delete;
void operator=(const MachineFunction&) = delete;
public:
MachineFunction(const Function *Fn, const TargetMachine &TM,
unsigned FunctionNum, MachineModuleInfo &MMI);
~MachineFunction();
MachineModuleInfo &getMMI() const { return MMI; }
MCContext &getContext() const { return Ctx; }
PseudoSourceValueManager &getPSVManager() const { return *PSVManager; }
const DataLayout &getDataLayout() const;
const Function *getFunction() const { return Fn; }
StringRef getName() const;
unsigned getFunctionNumber() const { return FunctionNumber; }
const TargetMachine &getTarget() const { return Target; }
const TargetSubtargetInfo &getSubtarget() const { return *STI; }
void setSubtarget(const TargetSubtargetInfo *ST) { STI = ST; }
template<typename STC> const STC &getSubtarget() const {
return *static_cast<const STC *>(STI);
}
MachineRegisterInfo &getRegInfo() { return *RegInfo; }
const MachineRegisterInfo &getRegInfo() const { return *RegInfo; }
MachineFrameInfo *getFrameInfo() { return FrameInfo; }
const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
MachineConstantPool *getConstantPool() { return ConstantPool; }
const MachineConstantPool *getConstantPool() const { return ConstantPool; }
const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; }
WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }
unsigned getAlignment() const { return Alignment; }
void setAlignment(unsigned A) { Alignment = A; }
void ensureAlignment(unsigned A) {
if (Alignment < A) Alignment = A;
}
bool exposesReturnsTwice() const {
return ExposesReturnsTwice;
}
void setExposesReturnsTwice(bool B) {
ExposesReturnsTwice = B;
}
bool hasInlineAsm() const {
return HasInlineAsm;
}
void setHasInlineAsm(bool B) {
HasInlineAsm = B;
}
template<typename Ty>
Ty *getInfo() {
if (!MFInfo)
MFInfo = Ty::template create<Ty>(Allocator, *this);
return static_cast<Ty*>(MFInfo);
}
template<typename Ty>
const Ty *getInfo() const {
return const_cast<MachineFunction*>(this)->getInfo<Ty>();
}
MachineBasicBlock *getBlockNumbered(unsigned N) const {
assert(N < MBBNumbering.size() && "Illegal block number");
assert(MBBNumbering[N] && "Block was removed from the machine function!");
return MBBNumbering[N];
}
bool shouldSplitStack() const;
unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
void RenumberBlocks(MachineBasicBlock *MBBFrom = nullptr);
void print(raw_ostream &OS, SlotIndexes* = nullptr) const;
void viewCFG() const;
void viewCFGOnly() const;
void dump() const;
void verify(Pass *p = nullptr, const char *Banner = nullptr) const;
typedef BasicBlockListType::iterator iterator;
typedef BasicBlockListType::const_iterator const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
static BasicBlockListType MachineFunction::*
getSublistAccess(MachineBasicBlock *) {
return &MachineFunction::BasicBlocks;
}
unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC);
iterator begin() { return BasicBlocks.begin(); }
const_iterator begin() const { return BasicBlocks.begin(); }
iterator end () { return BasicBlocks.end(); }
const_iterator end () const { return BasicBlocks.end(); }
reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
reverse_iterator rend () { return BasicBlocks.rend(); }
const_reverse_iterator rend () const { return BasicBlocks.rend(); }
unsigned size() const { return (unsigned)BasicBlocks.size();}
bool empty() const { return BasicBlocks.empty(); }
const MachineBasicBlock &front() const { return BasicBlocks.front(); }
MachineBasicBlock &front() { return BasicBlocks.front(); }
const MachineBasicBlock & back() const { return BasicBlocks.back(); }
MachineBasicBlock & back() { return BasicBlocks.back(); }
void push_back (MachineBasicBlock *MBB) { BasicBlocks.push_back (MBB); }
void push_front(MachineBasicBlock *MBB) { BasicBlocks.push_front(MBB); }
void insert(iterator MBBI, MachineBasicBlock *MBB) {
BasicBlocks.insert(MBBI, MBB);
}
void splice(iterator InsertPt, iterator MBBI) {
BasicBlocks.splice(InsertPt, BasicBlocks, MBBI);
}
void splice(iterator InsertPt, MachineBasicBlock *MBB) {
BasicBlocks.splice(InsertPt, BasicBlocks, MBB);
}
void splice(iterator InsertPt, iterator MBBI, iterator MBBE) {
BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE);
}
void remove(iterator MBBI) { BasicBlocks.remove(MBBI); }
void remove(MachineBasicBlock *MBBI) { BasicBlocks.remove(MBBI); }
void erase(iterator MBBI) { BasicBlocks.erase(MBBI); }
void erase(MachineBasicBlock *MBBI) { BasicBlocks.erase(MBBI); }
template <typename Comp>
void sort(Comp comp) {
BasicBlocks.sort(comp);
}
unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
MBBNumbering.push_back(MBB);
return (unsigned)MBBNumbering.size()-1;
}
void removeFromMBBNumbering(unsigned N) {
assert(N < MBBNumbering.size() && "Illegal basic block #");
MBBNumbering[N] = nullptr;
}
MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
DebugLoc DL,
bool NoImp = false);
MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
void DeleteMachineInstr(MachineInstr *MI);
MachineBasicBlock *CreateMachineBasicBlock(const BasicBlock *bb = nullptr);
void DeleteMachineBasicBlock(MachineBasicBlock *MBB);
MachineMemOperand *getMachineMemOperand(MachinePointerInfo PtrInfo,
unsigned f, uint64_t s,
unsigned base_alignment,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr);
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size);
typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
MachineOperand *allocateOperandArray(OperandCapacity Cap) {
return OperandRecycler.allocate(Cap, Allocator);
}
void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) {
OperandRecycler.deallocate(Cap, Array);
}
uint32_t *allocateRegisterMask(unsigned NumRegister) {
unsigned Size = (NumRegister + 31) / 32;
uint32_t *Mask = Allocator.Allocate<uint32_t>(Size);
for (unsigned i = 0; i != Size; ++i)
Mask[i] = 0;
return Mask;
}
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
std::pair<MachineInstr::mmo_iterator,
MachineInstr::mmo_iterator>
extractLoadMemRefs(MachineInstr::mmo_iterator Begin,
MachineInstr::mmo_iterator End);
std::pair<MachineInstr::mmo_iterator,
MachineInstr::mmo_iterator>
extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
MachineInstr::mmo_iterator End);
const char *createExternalSymbolName(StringRef Name);
MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
bool isLinkerPrivate = false) const;
MCSymbol *getPICBaseSymbol() const;
};
template <> struct GraphTraits<MachineFunction*> :
public GraphTraits<MachineBasicBlock*> {
static NodeType *getEntryNode(MachineFunction *F) {
return &F->front();
}
typedef MachineFunction::iterator nodes_iterator;
static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); }
static nodes_iterator nodes_end (MachineFunction *F) { return F->end(); }
static unsigned size (MachineFunction *F) { return F->size(); }
};
template <> struct GraphTraits<const MachineFunction*> :
public GraphTraits<const MachineBasicBlock*> {
static NodeType *getEntryNode(const MachineFunction *F) {
return &F->front();
}
typedef MachineFunction::const_iterator nodes_iterator;
static nodes_iterator nodes_begin(const MachineFunction *F) {
return F->begin();
}
static nodes_iterator nodes_end (const MachineFunction *F) {
return F->end();
}
static unsigned size (const MachineFunction *F) {
return F->size();
}
};
template <> struct GraphTraits<Inverse<MachineFunction*> > :
public GraphTraits<Inverse<MachineBasicBlock*> > {
static NodeType *getEntryNode(Inverse<MachineFunction*> G) {
return &G.Graph->front();
}
};
template <> struct GraphTraits<Inverse<const MachineFunction*> > :
public GraphTraits<Inverse<const MachineBasicBlock*> > {
static NodeType *getEntryNode(Inverse<const MachineFunction *> G) {
return &G.Graph->front();
}
};
}
#endif