X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineFunction.h;h=00a1fe884071e735ee5f8e6ab5dd8625a07bca95;hb=a727d5502c8e23c090da658bf14c5ebc1169a070;hp=742d4b5c0f851727fa9d0440213d42c5188316d8;hpb=1089790546ae7c5e8bcce99e60b19b3b23546bf3;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 742d4b5c0f8..00a1fe88407 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -1,125 +1,374 @@ -//===-- llvm/CodeGen/MachineCodeForMethod.h ----------------------*- C++ -*--=// -// -// Purpose: -// Collect native machine code information for a method. -// This allows target-specific information about the generated code -// to be stored with each method. +//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===// +// +// 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/Support/Annotation.h" +#include "llvm/ADT/BitVector.h" -#ifndef LLVM_CODEGEN_MACHINECODEFORMETHOD_H -#define LLVM_CODEGEN_MACHINECODEFORMETHOD_H +namespace llvm { -#include "llvm/Annotation.h" -#include "Support/NonCopyable.h" -#include "Support/HashExtras.h" -#include -class Value; class Function; -class Constant; -class Type; class TargetMachine; +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; -class MachineCodeForMethod : private Annotation { - hash_set constantsForConstPool; - hash_map offsets; - const Function* method; - unsigned staticStackSize; - unsigned automaticVarsSize; - unsigned regSpillsSize; - unsigned maxOptionalArgsSize; - unsigned maxOptionalNumArgs; - unsigned currentTmpValuesSize; - unsigned maxTmpValuesSize; - bool compiledAsLeaf; - bool spillsAreaFrozen; - bool automaticVarsAreaFrozen; - public: - /*ctor*/ MachineCodeForMethod(const Function* function, - const TargetMachine& target); - - // The next two methods are used to construct and to retrieve - // the MachineCodeForMethod 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. - // - static MachineCodeForMethod& construct(const Function *method, - const TargetMachine &target); - static void destruct(const Function *F); - static MachineCodeForMethod& get(const Function* function); - - // - // 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); + ilist_traits() : Parent(0) { } + + static MachineBasicBlock* getPrev(MachineBasicBlock* N) { return N->Prev; } + static MachineBasicBlock* getNext(MachineBasicBlock* N) { return N->Next; } + + 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 + 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; - void popAllTempValues (const TargetMachine& target); + // 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; - void freezeSpillsArea () { spillsAreaFrozen = true; } - void freezeAutomaticVarsArea () { automaticVarsAreaFrozen=true; } +public: + MachineFunction(const Function *Fn, const TargetMachine &TM); + ~MachineFunction(); + + /// getFunction - Return the LLVM function that this machine code represents + /// + const Function *getFunction() const { return Fn; } + + /// getTarget - Return the target machine this machine code is compiled with + /// + 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; } - int getOffset (const Value* val) const; + /// 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(); } - // int getOffsetFromFP (const Value* val) const; + /// 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); - void dump () const; + /// 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; + + /// construct - Allocate and initialize a MachineFunction for a given Function + /// and Target + /// + static MachineFunction& construct(const Function *F, const TargetMachine &TM); + + /// destruct - Destroy the MachineFunction corresponding to a given Function + /// + static void destruct(const Function *F); + + /// 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 ilist BasicBlockListType; + typedef BasicBlockListType::iterator iterator; + typedef BasicBlockListType::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; -private: - inline void incrementAutomaticVarsSize(int incr) { - automaticVarsSize+= incr; - staticStackSize += incr; + // Provide accessors for basic blocks... + const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; } + BasicBlockListType &getBasicBlockList() { return BasicBlocks; } + + //===--------------------------------------------------------------------===// + // BasicBlock iterator forwarding functions + // + 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 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(); } + + //===--------------------------------------------------------------------===// + // Internal functions used to automatically number MachineBasicBlocks + // + + /// 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; } - inline void incrementRegSpillsSize(int incr) { - regSpillsSize+= incr; - staticStackSize += incr; + + /// 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; } - inline void incrementTmpAreaSize(int incr) { - currentTmpValuesSize += incr; - if (maxTmpValuesSize < currentTmpValuesSize) - { - staticStackSize += currentTmpValuesSize - maxTmpValuesSize; - maxTmpValuesSize = currentTmpValuesSize; - } +}; + +//===--------------------------------------------------------------------===// +// 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 resetTmpAreaSize() { - currentTmpValuesSize = 0; + + // 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(); + } + + // 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(); } - int allocateOptionalArg (const TargetMachine& target, - const Type* type); }; +template <> struct GraphTraits > : + public GraphTraits > { + static NodeType *getEntryNode(Inverse G) { + return &G.Graph->front(); + } +}; + +} // End llvm namespace #endif