X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineFunction.h;h=00a1fe884071e735ee5f8e6ab5dd8625a07bca95;hb=a727d5502c8e23c090da658bf14c5ebc1169a070;hp=0e0aa51036744e38522a9410ba401be72b5a150c;hpb=7b8ba17761180d272d7fa0c1c7371e5b0b9b3872;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 0e0aa510367..00a1fe88407 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -1,58 +1,127 @@ //===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===// -// -// Collect native machine code information for a method. This allows -// target-specific information about the generated code to be stored with each -// method. -// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Collect native machine code for a function. This class contains a list of +// MachineBasicBlock instances that make up the current compiled function. +// +// This class also contains pointers to various classes which hold +// target-specific information about the generated code. +// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H #define LLVM_CODEGEN_MACHINEFUNCTION_H +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/SSARegMap.h" -#include "llvm/Annotation.h" -#include "Support/HashExtras.h" -#include "Support/hash_set" -#include "Support/ilist" +#include "llvm/Support/Annotation.h" +#include "llvm/ADT/BitVector.h" + +namespace llvm { -class Value; class Function; -class Constant; -class Type; class TargetMachine; -class Pass; +class SSARegMap; +class MachineFrameInfo; +class MachineConstantPool; +class MachineJumpTableInfo; + +// ilist_traits +template <> +struct ilist_traits { + // this is only set by the MachineFunction owning the ilist + friend class MachineFunction; + MachineFunction* Parent; + +public: + ilist_traits() : Parent(0) { } + + static MachineBasicBlock* getPrev(MachineBasicBlock* N) { return N->Prev; } + static MachineBasicBlock* getNext(MachineBasicBlock* N) { return N->Next; } -Pass *createMachineCodeConstructionPass(TargetMachine &Target); -Pass *createMachineCodeDestructionPass(); -Pass *createMachineFunctionPrinterPass(); + static const MachineBasicBlock* + getPrev(const MachineBasicBlock* N) { return N->Prev; } + + static const MachineBasicBlock* + getNext(const MachineBasicBlock* N) { return N->Next; } + + static void setPrev(MachineBasicBlock* N, MachineBasicBlock* prev) { + N->Prev = prev; + } + static void setNext(MachineBasicBlock* N, MachineBasicBlock* next) { + N->Next = next; + } + + static MachineBasicBlock* createSentinel(); + static void destroySentinel(MachineBasicBlock *MBB) { delete MBB; } + void addNodeToList(MachineBasicBlock* N); + void removeNodeFromList(MachineBasicBlock* N); + void transferNodesFromList(iplist > &toList, + ilist_iterator first, + ilist_iterator last); +}; + +/// MachineFunctionInfo - This class can be derived from and used by targets to +/// hold private target-specific information for each MachineFunction. Objects +/// of type are accessed/created with MF::getInfo and destroyed when the +/// MachineFunction is destroyed. +struct MachineFunctionInfo { + virtual ~MachineFunctionInfo() {}; +}; class MachineFunction : private Annotation { const Function *Fn; const TargetMachine &Target; // List of machine basic blocks in function - iplist BasicBlocks; - - // FIXME: State should be held elsewhere... - hash_set constantsForConstPool; - hash_map offsets; - unsigned staticStackSize; - unsigned automaticVarsSize; - unsigned regSpillsSize; - unsigned maxOptionalArgsSize; - unsigned maxOptionalNumArgs; - unsigned currentTmpValuesSize; - unsigned maxTmpValuesSize; - bool compiledAsLeaf; - bool spillsAreaFrozen; - bool automaticVarsAreaFrozen; + ilist BasicBlocks; // Keeping track of mapping from SSA values to registers SSARegMap *SSARegMapping; + + // Used to keep track of target-specific per-machine function information for + // the target implementation. + MachineFunctionInfo *MFInfo; + + // Keep track of objects allocated on the stack. + MachineFrameInfo *FrameInfo; + + // Keep track of constants which are spilled to memory + MachineConstantPool *ConstantPool; + + // Keep track of jump tables for switch instructions + MachineJumpTableInfo *JumpTableInfo; + + // Function-level unique numbering for MachineBasicBlocks. When a + // MachineBasicBlock is inserted into a MachineFunction is it automatically + // numbered and this vector keeps track of the mapping from ID's to MBB's. + std::vector MBBNumbering; + + /// UsedPhysRegs - This is a bit vector that is computed and set by the + /// register allocator, and must be kept up to date by passes that run after + /// register allocation (though most don't modify this). This is used + /// so that the code generator knows which callee save registers to save and + /// for other target specific uses. + BitVector UsedPhysRegs; + + /// LiveIns/LiveOuts - Keep track of the physical registers that are + /// livein/liveout of the function. Live in values are typically arguments in + /// registers, live out values are typically return values in registers. + /// LiveIn values are allowed to have virtual registers associated with them, + /// stored in the second element. + std::vector > LiveIns; + std::vector LiveOuts; public: - MachineFunction(const Function *Fn, const TargetMachine& target); + MachineFunction(const Function *Fn, const TargetMachine &TM); + ~MachineFunction(); /// getFunction - Return the LLVM function that this machine code represents /// @@ -62,48 +131,143 @@ public: /// const TargetMachine &getTarget() const { return Target; } + /// SSARegMap Interface... Keep track of information about each SSA virtual + /// register, such as which register class it belongs to. + /// + SSARegMap *getSSARegMap() const { return SSARegMapping; } + void clearSSARegMap(); + + /// getFrameInfo - Return the frame info object for the current function. + /// This object contains information about objects allocated on the stack + /// frame of the current function in an abstract way. + /// + MachineFrameInfo *getFrameInfo() const { return FrameInfo; } + + /// getJumpTableInfo - Return the jump table info object for the current + /// function. This object contains information about jump tables for switch + /// instructions in the current function. + /// + MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; } + + /// getConstantPool - Return the constant pool object for the current + /// function. + /// + MachineConstantPool *getConstantPool() const { return ConstantPool; } + + /// MachineFunctionInfo - Keep track of various per-function pieces of + /// information for backends that would like to do so. + /// + template + Ty *getInfo() { + if (!MFInfo) MFInfo = new Ty(*this); + + assert((void*)dynamic_cast(MFInfo) == (void*)MFInfo && + "Invalid concrete type or multiple inheritence for getInfo"); + return static_cast(MFInfo); + } + + template + const Ty *getInfo() const { + return const_cast(this)->getInfo(); + } + + /// isPhysRegUsed - Return true if the specified register is used in this + /// function. This only works after register allocation. + bool isPhysRegUsed(unsigned Reg) const { return UsedPhysRegs[Reg]; } + + /// setPhysRegUsed - Mark the specified register used in this function. + /// This should only be called during and after register allocation. + void setPhysRegUsed(unsigned Reg) { UsedPhysRegs[Reg] = true; } + + /// setPhysRegUnused - Mark the specified register unused in this function. + /// This should only be called during and after register allocation. + void setPhysRegUnused(unsigned Reg) { UsedPhysRegs[Reg] = false; } + + // LiveIn/LiveOut management methods. + + /// addLiveIn/Out - Add the specified register as a live in/out. Note that it + /// is an error to add the same register to the same set more than once. + void addLiveIn(unsigned Reg, unsigned vreg = 0) { + LiveIns.push_back(std::make_pair(Reg, vreg)); + } + void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); } + + // Iteration support for live in/out sets. These sets are kept in sorted + // order by their register number. + typedef std::vector >::const_iterator + livein_iterator; + typedef std::vector::const_iterator liveout_iterator; + livein_iterator livein_begin() const { return LiveIns.begin(); } + livein_iterator livein_end() const { return LiveIns.end(); } + bool livein_empty() const { return LiveIns.empty(); } + liveout_iterator liveout_begin() const { return LiveOuts.begin(); } + liveout_iterator liveout_end() const { return LiveOuts.end(); } + bool liveout_empty() const { return LiveOuts.empty(); } + + /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they + /// are inserted into the machine function. The block number for a machine + /// basic block can be found by using the MBB::getBlockNumber method, this + /// method provides the inverse mapping. + /// + MachineBasicBlock *getBlockNumbered(unsigned N) { + assert(N < MBBNumbering.size() && "Illegal block number"); + assert(MBBNumbering[N] && "Block was removed from the machine function!"); + return MBBNumbering[N]; + } + + /// getNumBlockIDs - Return the number of MBB ID's allocated. + /// + unsigned getNumBlockIDs() const { return MBBNumbering.size(); } + + /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and + /// recomputes them. This guarantees that the MBB numbers are sequential, + /// dense, and match the ordering of the blocks within the function. If a + /// specific MachineBasicBlock is specified, only that block and those after + /// it are renumbered. + void RenumberBlocks(MachineBasicBlock *MBBFrom = 0); + /// print - Print out the MachineFunction in a format suitable for debugging /// to the specified stream. /// void print(std::ostream &OS) const; + void print(std::ostream *OS) const { if (OS) print(*OS); } + + /// viewCFG - This function is meant for use from the debugger. You can just + /// say 'call F->viewCFG()' and a ghostview window should pop up from the + /// program, displaying the CFG of the current function with the code for each + /// basic block inside. This depends on there being a 'dot' and 'gv' program + /// in your path. + /// + void viewCFG() const; + + /// viewCFGOnly - This function is meant for use from the debugger. It works + /// just like viewCFG, but it does not include the contents of basic blocks + /// into the nodes, just the label. If you are only interested in the CFG + /// this can make the graph smaller. + /// + void viewCFGOnly() const; /// dump - Print the current MachineFunction to cerr, useful for debugger use. /// void dump() const; - /// CalculateArgSize - Call this method to fill in the maxOptionalArgsSize & - /// staticStackSize fields... + /// construct - Allocate and initialize a MachineFunction for a given Function + /// and Target /// - void CalculateArgSize(); + static MachineFunction& construct(const Function *F, const TargetMachine &TM); - // The next three methods are used to construct, destruct, and retrieve the - // MachineFunction object for the given method. - // - // construct() -- Allocates and initializes for a given method and target - // get() -- Returns a handle to the object. - // This should not be called before "construct()" - // for a given Method. - // destruct() -- Destroy the MachineFunction object - // - static MachineFunction& construct(const Function *Fn, - const TargetMachine &target); + /// destruct - Destroy the MachineFunction corresponding to a given Function + /// static void destruct(const Function *F); - static MachineFunction& get(const Function *F); - // Getting and storing SSARegMap information - const TargetRegisterClass* getRegClass(unsigned Reg) { - return SSARegMapping->getRegClass(Reg); - } - void addRegMap(unsigned Reg, const TargetRegisterClass *RegClass) { - SSARegMapping->addRegMap(Reg, RegClass); - } - void clearSSARegMap() { - delete SSARegMapping; - SSARegMapping = NULL; - } + /// get - Return a handle to a MachineFunction corresponding to the given + /// Function. This should not be called before "construct()" for a given + /// Function. + /// + static MachineFunction& get(const Function *F); // Provide accessors for the MachineBasicBlock list... - typedef iplist BasicBlockListType; + typedef ilist BasicBlockListType; typedef BasicBlockListType::iterator iterator; typedef BasicBlockListType::const_iterator const_iterator; typedef std::reverse_iterator const_reverse_iterator; @@ -112,7 +276,7 @@ public: // Provide accessors for basic blocks... const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; } BasicBlockListType &getBasicBlockList() { return BasicBlocks; } - + //===--------------------------------------------------------------------===// // BasicBlock iterator forwarding functions // @@ -134,78 +298,77 @@ public: MachineBasicBlock & back() { return BasicBlocks.back(); } //===--------------------------------------------------------------------===// - // - // FIXME: Most of the following state should be moved out to passes that use - // it, instead of being put here. + // Internal functions used to automatically number MachineBasicBlocks // - // - // Accessors for global information about generated code for a method. - // - inline bool isCompiledAsLeafMethod() const { return compiledAsLeaf; } - inline unsigned getStaticStackSize() const { return staticStackSize; } - inline unsigned getAutomaticVarsSize() const { return automaticVarsSize; } - inline unsigned getRegSpillsSize() const { return regSpillsSize; } - inline unsigned getMaxOptionalArgsSize() const { return maxOptionalArgsSize;} - inline unsigned getMaxOptionalNumArgs() const { return maxOptionalNumArgs;} - inline const hash_set& - getConstantPoolValues() const {return constantsForConstPool;} - - // - // Modifiers used during code generation - // - void initializeFrameLayout (const TargetMachine& target); - - void addToConstantPool (const Constant* constVal) - { constantsForConstPool.insert(constVal); } - - inline void markAsLeafMethod() { compiledAsLeaf = true; } - - int computeOffsetforLocalVar (const TargetMachine& target, - const Value* local, - unsigned int& getPaddedSize, - unsigned int sizeToUse = 0); - int allocateLocalVar (const TargetMachine& target, - const Value* local, - unsigned int sizeToUse = 0); - - int allocateSpilledValue (const TargetMachine& target, - const Type* type); - - int pushTempValue (const TargetMachine& target, - unsigned int size); - - void popAllTempValues (const TargetMachine& target); - - void freezeSpillsArea () { spillsAreaFrozen = true; } - void freezeAutomaticVarsArea () { automaticVarsAreaFrozen=true; } - - int getOffset (const Value* val) const; - - // int getOffsetFromFP (const Value* val) const; - -private: - inline void incrementAutomaticVarsSize(int incr) { - automaticVarsSize+= incr; - staticStackSize += incr; + /// getNextMBBNumber - Returns the next unique number to be assigned + /// to a MachineBasicBlock in this MachineFunction. + /// + unsigned addToMBBNumbering(MachineBasicBlock *MBB) { + MBBNumbering.push_back(MBB); + return MBBNumbering.size()-1; + } + + /// removeFromMBBNumbering - Remove the specific machine basic block from our + /// tracker, this is only really to be used by the MachineBasicBlock + /// implementation. + void removeFromMBBNumbering(unsigned N) { + assert(N < MBBNumbering.size() && "Illegal basic block #"); + MBBNumbering[N] = 0; + } +}; + +//===--------------------------------------------------------------------===// +// GraphTraits specializations for function basic block graphs (CFGs) +//===--------------------------------------------------------------------===// + +// Provide specializations of GraphTraits to be able to treat a +// machine function as a graph of machine basic blocks... these are +// the same as the machine basic block iterators, except that the root +// node is implicitly the first node of the function. +// +template <> struct GraphTraits : + public GraphTraits { + static NodeType *getEntryNode(MachineFunction *F) { + return &F->front(); } - inline void incrementRegSpillsSize(int incr) { - regSpillsSize+= incr; - staticStackSize += incr; + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + 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(); } +}; +template <> struct GraphTraits : + public GraphTraits { + static NodeType *getEntryNode(const MachineFunction *F) { + return &F->front(); } - inline void incrementTmpAreaSize(int incr) { - currentTmpValuesSize += incr; - if (maxTmpValuesSize < currentTmpValuesSize) - { - staticStackSize += currentTmpValuesSize - maxTmpValuesSize; - maxTmpValuesSize = currentTmpValuesSize; - } + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + 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(); } +}; + + +// Provide specializations of GraphTraits to be able to treat a function as a +// graph of basic blocks... and to walk it in inverse order. Inverse order for +// a function is considered to be when traversing the predecessor edges of a BB +// instead of the successor edges. +// +template <> struct GraphTraits > : + public GraphTraits > { + static NodeType *getEntryNode(Inverse G) { + return &G.Graph->front(); } - inline void resetTmpAreaSize() { - currentTmpValuesSize = 0; +}; +template <> struct GraphTraits > : + public GraphTraits > { + static NodeType *getEntryNode(Inverse G) { + return &G.Graph->front(); } - int allocateOptionalArg (const TargetMachine& target, - const Type* type); }; +} // End llvm namespace + #endif