X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FFastISel.h;h=7cb96952aa6168af3c74bf7aefd9aad568be5464;hb=2131eb48875c7059eb04f0a324321e1e15e6597e;hp=113dcc7c78ad661bf1f392b8e6ca0169c85424a5;hpb=db4971259ce94cea26e555e9ade82672a3581f5c;p=oota-llvm.git diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 113dcc7c78a..7cb96952aa6 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -8,23 +8,24 @@ //===----------------------------------------------------------------------===// // // This file defines the FastISel class. -// +// //===----------------------------------------------------------------------===// - + #ifndef LLVM_CODEGEN_FASTISEL_H #define LLVM_CODEGEN_FASTISEL_H #include "llvm/ADT/DenseMap.h" -#ifndef NDEBUG -#include "llvm/ADT/SmallSet.h" -#endif #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/MachineBasicBlock.h" namespace llvm { class AllocaInst; +class Constant; class ConstantFP; +class FunctionLoweringInfo; class Instruction; +class LoadInst; class MachineBasicBlock; class MachineConstantPool; class MachineFunction; @@ -33,26 +34,21 @@ class MachineFrameInfo; class MachineRegisterInfo; class TargetData; class TargetInstrInfo; +class TargetLibraryInfo; class TargetLowering; class TargetMachine; class TargetRegisterClass; class TargetRegisterInfo; +class User; +class Value; /// FastISel - This is a fast-path instruction selection class that /// generates poor code and doesn't support illegal types or non-trivial /// lowering, but runs quickly. class FastISel { protected: - MachineBasicBlock *MBB; DenseMap LocalValueMap; - DenseMap &ValueMap; - DenseMap &MBBMap; - DenseMap &StaticAllocaMap; - std::vector > &PHINodesToUpdate; -#ifndef NDEBUG - SmallSet &CatchInfoLost; -#endif - MachineFunction &MF; + FunctionLoweringInfo &FuncInfo; MachineRegisterInfo &MRI; MachineFrameInfo &MFI; MachineConstantPool &MCP; @@ -62,23 +58,35 @@ protected: const TargetInstrInfo &TII; const TargetLowering &TLI; const TargetRegisterInfo &TRI; - bool IsBottomUp; + const TargetLibraryInfo *LibInfo; + + /// The position of the last instruction for materializing constants + /// for use in the current block. It resets to EmitStartPt when it + /// makes sense (for example, it's usually profitable to avoid function + /// calls between the definition and the use) + MachineInstr *LastLocalValue; + + /// The top most instruction in the current block that is allowed for + /// emitting local variables. LastLocalValue resets to EmitStartPt when + /// it makes sense (for example, on function calls) + MachineInstr *EmitStartPt; public: - /// startNewBlock - Set the current block to which generated machine - /// instructions will be appended, and clear the local CSE map. - /// - void startNewBlock(MachineBasicBlock *mbb) { - setCurrentBlock(mbb); - LocalValueMap.clear(); + /// getLastLocalValue - Return the position of the last instruction + /// emitted for materializing constants for use in the current block. + MachineInstr *getLastLocalValue() { return LastLocalValue; } + + /// setLastLocalValue - Update the position of the last instruction + /// emitted for materializing constants for use in the current block. + void setLastLocalValue(MachineInstr *I) { + EmitStartPt = I; + LastLocalValue = I; } - /// setCurrentBlock - Set the current block to which generated machine - /// instructions will be appended. + /// startNewBlock - Set the current block to which generated machine + /// instructions will be appended, and clear the local CSE map. /// - void setCurrentBlock(MachineBasicBlock *mbb) { - MBB = mbb; - } + void startNewBlock(); /// getCurDebugLoc() - Return current debug location information. DebugLoc getCurDebugLoc() const { return DL; } @@ -110,18 +118,36 @@ public: /// index value. std::pair getRegForGEPIndex(const Value *V); + /// TryToFoldLoad - The specified machine instr operand is a vreg, and that + /// vreg is being provided by the specified load instruction. If possible, + /// try to fold the load as an operand to the instruction, returning true if + /// possible. + virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/, + const LoadInst * /*LI*/) { + return false; + } + + /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions + /// into the current block. + void recomputeInsertPt(); + + struct SavePoint { + MachineBasicBlock::iterator InsertPt; + DebugLoc DL; + }; + + /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions + /// into the local value area and return the old insert position. + SavePoint enterLocalValueArea(); + + /// leaveLocalValueArea - Reset InsertPt to the given old insert position. + void leaveLocalValueArea(SavePoint Old); + virtual ~FastISel(); protected: - FastISel(MachineFunction &mf, - DenseMap &vm, - DenseMap &bm, - DenseMap &am, - std::vector > &PHINodesToUpdate -#ifndef NDEBUG - , SmallSet &cil -#endif - ); + explicit FastISel(FunctionLoweringInfo &funcInfo, + const TargetLibraryInfo *libInfo); /// TargetSelectInstruction - This method is called by target-independent /// code when the normal FastISel process fails to select an instruction. @@ -196,16 +222,7 @@ protected: unsigned Opcode, unsigned Op0, bool Op0IsKill, uint64_t Imm, MVT ImmType); - - /// FastEmit_rf_ - This method is a wrapper of FastEmit_rf. It first tries - /// to emit an instruction with an immediate operand using FastEmit_rf. - /// If that fails, it materializes the immediate into a register and try - /// FastEmit_rr instead. - unsigned FastEmit_rf_(MVT VT, - unsigned Opcode, - unsigned Op0, bool Op0IsKill, - const ConstantFP *FPImm, MVT ImmType); - + /// FastEmit_i - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and /// immediate operand be emitted. @@ -243,14 +260,31 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); - /// FastEmitInst_ri - Emit a MachineInstr with two register operands + /// FastEmitInst_rrr - Emit a MachineInstr with three register operands /// and a result register in the given register class. /// + unsigned FastEmitInst_rrr(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill, + unsigned Op2, bool Op2IsKill); + + /// FastEmitInst_ri - Emit a MachineInstr with a register operand, + /// an immediate, and a result register in the given register class. + /// unsigned FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm); + /// FastEmitInst_rii - Emit a MachineInstr with one register operand + /// and two immediate operands. + /// + unsigned FastEmitInst_rii(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_rf - Emit a MachineInstr with two register operands /// and a result register in the given register class. /// @@ -267,13 +301,27 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill, uint64_t Imm); - + + /// FastEmitInst_rrii - Emit a MachineInstr with two register operands, + /// two immediates operands, and a result register in the given register + /// class. + unsigned FastEmitInst_rrii(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_i - Emit a MachineInstr with a single immediate /// operand, and a result register in the given register class. unsigned FastEmitInst_i(unsigned MachineInstrOpcode, const TargetRegisterClass *RC, uint64_t Imm); + /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands. + unsigned FastEmitInst_ii(unsigned MachineInstrOpcode, + const TargetRegisterClass *RC, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg /// from a specified index of a superregister to a specified type. unsigned FastEmitInst_extractsubreg(MVT RetVT, @@ -290,11 +338,11 @@ protected: /// the CFG. void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL); - unsigned UpdateValueMap(const Value* I, unsigned Reg); + void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1); unsigned createResultReg(const TargetRegisterClass *RC); - - /// TargetMaterializeConstant - Emit a constant in a register using + + /// TargetMaterializeConstant - Emit a constant in a register using /// target-specific logic, such as constant pool loads. virtual unsigned TargetMaterializeConstant(const Constant* C) { return 0; @@ -306,6 +354,10 @@ protected: return 0; } + virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) { + return 0; + } + private: bool SelectBinaryOp(const User *I, unsigned ISDOpcode); @@ -316,9 +368,13 @@ private: bool SelectCall(const User *I); bool SelectBitCast(const User *I); - + bool SelectCast(const User *I, unsigned Opcode); + bool SelectExtractValue(const User *I); + + bool SelectInsertValue(const User *I); + /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. /// Emit code to ensure constants are copied into registers when needed. /// Remember the virtual registers that need to be added to the Machine PHI @@ -332,8 +388,17 @@ private: /// be materialized with new instructions. unsigned materializeRegForValue(const Value *V, MVT VT); + /// flushLocalValueMap - clears LocalValueMap and moves the area for the + /// new local variables to the beginning of the block. It helps to avoid + /// spilling cached variables across heavy instructions like calls. + void flushLocalValueMap(); + /// hasTrivialKill - Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V) const; + + /// removeDeadCode - Remove all dead instructions between the I and E. + void removeDeadCode(MachineBasicBlock::iterator I, + MachineBasicBlock::iterator E); }; }