| //===-- FastISel.h - Definition of the FastISel class ---------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the FastISel class. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CODEGEN_FASTISEL_H |
| #define LLVM_CODEGEN_FASTISEL_H |
| |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/CodeGen/ValueTypes.h" |
| #include "llvm/CodeGen/MachineBasicBlock.h" |
| |
| namespace llvm { |
| |
| class AllocaInst; |
| class ConstantFP; |
| class FunctionLoweringInfo; |
| class Instruction; |
| class MachineBasicBlock; |
| class MachineConstantPool; |
| class MachineFunction; |
| class MachineInstr; |
| class MachineFrameInfo; |
| class MachineRegisterInfo; |
| class TargetData; |
| class TargetInstrInfo; |
| class TargetLowering; |
| class TargetMachine; |
| class TargetRegisterClass; |
| class TargetRegisterInfo; |
| class LoadInst; |
| |
| /// 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: |
| DenseMap<const Value *, unsigned> LocalValueMap; |
| FunctionLoweringInfo &FuncInfo; |
| MachineRegisterInfo &MRI; |
| MachineFrameInfo &MFI; |
| MachineConstantPool &MCP; |
| DebugLoc DL; |
| const TargetMachine &TM; |
| const TargetData &TD; |
| const TargetInstrInfo &TII; |
| const TargetLowering &TLI; |
| const TargetRegisterInfo &TRI; |
| |
| /// 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: |
| /// 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; |
| } |
| |
| /// startNewBlock - Set the current block to which generated machine |
| /// instructions will be appended, and clear the local CSE map. |
| /// |
| void startNewBlock(); |
| |
| /// getCurDebugLoc() - Return current debug location information. |
| DebugLoc getCurDebugLoc() const { return DL; } |
| |
| /// SelectInstruction - Do "fast" instruction selection for the given |
| /// LLVM IR instruction, and append generated machine instructions to |
| /// the current block. Return true if selection was successful. |
| /// |
| bool SelectInstruction(const Instruction *I); |
| |
| /// SelectOperator - Do "fast" instruction selection for the given |
| /// LLVM IR operator (Instruction or ConstantExpr), and append |
| /// generated machine instructions to the current block. Return true |
| /// if selection was successful. |
| /// |
| bool SelectOperator(const User *I, unsigned Opcode); |
| |
| /// getRegForValue - Create a virtual register and arrange for it to |
| /// be assigned the value for the given LLVM value. |
| unsigned getRegForValue(const Value *V); |
| |
| /// lookUpRegForValue - Look up the value to see if its value is already |
| /// cached in a register. It may be defined by instructions across blocks or |
| /// defined locally. |
| unsigned lookUpRegForValue(const Value *V); |
| |
| /// getRegForGEPIndex - This is a wrapper around getRegForValue that also |
| /// takes care of truncating or sign-extending the given getelementptr |
| /// index value. |
| std::pair<unsigned, bool> 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: |
| explicit FastISel(FunctionLoweringInfo &funcInfo); |
| |
| /// TargetSelectInstruction - This method is called by target-independent |
| /// code when the normal FastISel process fails to select an instruction. |
| /// This gives targets a chance to emit code for anything that doesn't |
| /// fit into FastISel's framework. It returns true if it was successful. |
| /// |
| virtual bool |
| TargetSelectInstruction(const Instruction *I) = 0; |
| |
| /// FastEmit_r - This method is called by target-independent code |
| /// to request that an instruction with the given type and opcode |
| /// be emitted. |
| virtual unsigned FastEmit_(MVT VT, |
| MVT RetVT, |
| unsigned Opcode); |
| |
| /// FastEmit_r - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// register operand be emitted. |
| /// |
| virtual unsigned FastEmit_r(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill); |
| |
| /// FastEmit_rr - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// register operands be emitted. |
| /// |
| virtual unsigned FastEmit_rr(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill, |
| unsigned Op1, bool Op1IsKill); |
| |
| /// FastEmit_ri - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// register and immediate operands be emitted. |
| /// |
| virtual unsigned FastEmit_ri(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill, |
| uint64_t Imm); |
| |
| /// FastEmit_rf - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// register and floating-point immediate operands be emitted. |
| /// |
| virtual unsigned FastEmit_rf(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill, |
| const ConstantFP *FPImm); |
| |
| /// FastEmit_rri - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// register and immediate operands be emitted. |
| /// |
| virtual unsigned FastEmit_rri(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill, |
| unsigned Op1, bool Op1IsKill, |
| uint64_t Imm); |
| |
| /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries |
| /// to emit an instruction with an immediate operand using FastEmit_ri. |
| /// If that fails, it materializes the immediate into a register and try |
| /// FastEmit_rr instead. |
| unsigned FastEmit_ri_(MVT VT, |
| unsigned Opcode, |
| unsigned Op0, bool Op0IsKill, |
| uint64_t Imm, 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. |
| virtual unsigned FastEmit_i(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| uint64_t Imm); |
| |
| /// FastEmit_f - This method is called by target-independent code |
| /// to request that an instruction with the given type, opcode, and |
| /// floating-point immediate operand be emitted. |
| virtual unsigned FastEmit_f(MVT VT, |
| MVT RetVT, |
| unsigned Opcode, |
| const ConstantFP *FPImm); |
| |
| /// FastEmitInst_ - Emit a MachineInstr with no operands and a |
| /// result register in the given register class. |
| /// |
| unsigned FastEmitInst_(unsigned MachineInstOpcode, |
| const TargetRegisterClass *RC); |
| |
| /// FastEmitInst_r - Emit a MachineInstr with one register operand |
| /// and a result register in the given register class. |
| /// |
| unsigned FastEmitInst_r(unsigned MachineInstOpcode, |
| const TargetRegisterClass *RC, |
| unsigned Op0, bool Op0IsKill); |
| |
| /// FastEmitInst_rr - Emit a MachineInstr with two register operands |
| /// and a result register in the given register class. |
| /// |
| unsigned FastEmitInst_rr(unsigned MachineInstOpcode, |
| const TargetRegisterClass *RC, |
| unsigned Op0, bool Op0IsKill, |
| unsigned Op1, bool Op1IsKill); |
| |
| /// 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. |
| /// |
| unsigned FastEmitInst_rf(unsigned MachineInstOpcode, |
| const TargetRegisterClass *RC, |
| unsigned Op0, bool Op0IsKill, |
| const ConstantFP *FPImm); |
| |
| /// FastEmitInst_rri - Emit a MachineInstr with two register operands, |
| /// an immediate, and a result register in the given register class. |
| /// |
| unsigned FastEmitInst_rri(unsigned MachineInstOpcode, |
| const TargetRegisterClass *RC, |
| unsigned Op0, bool Op0IsKill, |
| unsigned Op1, bool Op1IsKill, |
| uint64_t Imm); |
| |
| /// 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, |
| unsigned Op0, bool Op0IsKill, |
| uint32_t Idx); |
| |
| /// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op |
| /// with all but the least significant bit set to zero. |
| unsigned FastEmitZExtFromI1(MVT VT, |
| unsigned Op0, bool Op0IsKill); |
| |
| /// FastEmitBranch - Emit an unconditional branch to the given block, |
| /// unless it is the immediate (fall-through) successor, and update |
| /// the CFG. |
| void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL); |
| |
| void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1); |
| |
| unsigned createResultReg(const TargetRegisterClass *RC); |
| |
| /// TargetMaterializeConstant - Emit a constant in a register using |
| /// target-specific logic, such as constant pool loads. |
| virtual unsigned TargetMaterializeConstant(const Constant* C) { |
| return 0; |
| } |
| |
| /// TargetMaterializeAlloca - Emit an alloca address in a register using |
| /// target-specific logic. |
| virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) { |
| return 0; |
| } |
| |
| virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) { |
| return 0; |
| } |
| |
| private: |
| bool SelectBinaryOp(const User *I, unsigned ISDOpcode); |
| |
| bool SelectFNeg(const User *I); |
| |
| bool SelectGetElementPtr(const User *I); |
| |
| bool SelectCall(const User *I); |
| |
| bool SelectBitCast(const User *I); |
| |
| bool SelectCast(const User *I, unsigned Opcode); |
| |
| bool SelectExtractValue(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 |
| /// nodes as input. We cannot just directly add them, because expansion |
| /// might result in multiple MBB's for one BB. As such, the start of the |
| /// BB might correspond to a different MBB than the end. |
| bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); |
| |
| /// materializeRegForValue - Helper for getRegForVale. This function is |
| /// called when the value isn't already available in a register and must |
| /// 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; |
| }; |
| |
| } |
| |
| #endif |