| //===-- SelectionDAGBuilder.h - Selection-DAG building --------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This implements routines for translating from LLVM IR into SelectionDAG IR. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef SELECTIONDAGBUILDER_H | |
| #define SELECTIONDAGBUILDER_H | |
| #include "llvm/Constants.h" | |
| #include "llvm/CodeGen/SelectionDAG.h" | |
| #include "llvm/ADT/APInt.h" | |
| #include "llvm/ADT/DenseMap.h" | |
| #include "llvm/CodeGen/SelectionDAGNodes.h" | |
| #include "llvm/CodeGen/ValueTypes.h" | |
| #include "llvm/Support/CallSite.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| #include <vector> | |
| namespace llvm { | |
| class AliasAnalysis; | |
| class AllocaInst; | |
| class BasicBlock; | |
| class BitCastInst; | |
| class BranchInst; | |
| class CallInst; | |
| class DbgValueInst; | |
| class ExtractElementInst; | |
| class ExtractValueInst; | |
| class FCmpInst; | |
| class FPExtInst; | |
| class FPToSIInst; | |
| class FPToUIInst; | |
| class FPTruncInst; | |
| class Function; | |
| class FunctionLoweringInfo; | |
| class GetElementPtrInst; | |
| class GCFunctionInfo; | |
| class ICmpInst; | |
| class IntToPtrInst; | |
| class IndirectBrInst; | |
| class InvokeInst; | |
| class InsertElementInst; | |
| class InsertValueInst; | |
| class Instruction; | |
| class LoadInst; | |
| class MachineBasicBlock; | |
| class MachineInstr; | |
| class MachineRegisterInfo; | |
| class MDNode; | |
| class PHINode; | |
| class PtrToIntInst; | |
| class ReturnInst; | |
| class SDDbgValue; | |
| class SExtInst; | |
| class SelectInst; | |
| class ShuffleVectorInst; | |
| class SIToFPInst; | |
| class StoreInst; | |
| class SwitchInst; | |
| class TargetData; | |
| class TargetLowering; | |
| class TruncInst; | |
| class UIToFPInst; | |
| class UnreachableInst; | |
| class UnwindInst; | |
| class VAArgInst; | |
| class ZExtInst; | |
| //===----------------------------------------------------------------------===// | |
| /// SelectionDAGBuilder - This is the common target-independent lowering | |
| /// implementation that is parameterized by a TargetLowering object. | |
| /// | |
| class SelectionDAGBuilder { | |
| /// CurDebugLoc - current file + line number. Changes as we build the DAG. | |
| DebugLoc CurDebugLoc; | |
| DenseMap<const Value*, SDValue> NodeMap; | |
| /// UnusedArgNodeMap - Maps argument value for unused arguments. This is used | |
| /// to preserve debug information for incoming arguments. | |
| DenseMap<const Value*, SDValue> UnusedArgNodeMap; | |
| /// DanglingDebugInfo - Helper type for DanglingDebugInfoMap. | |
| class DanglingDebugInfo { | |
| const DbgValueInst* DI; | |
| DebugLoc dl; | |
| unsigned SDNodeOrder; | |
| public: | |
| DanglingDebugInfo() : DI(0), dl(DebugLoc()), SDNodeOrder(0) { } | |
| DanglingDebugInfo(const DbgValueInst *di, DebugLoc DL, unsigned SDNO) : | |
| DI(di), dl(DL), SDNodeOrder(SDNO) { } | |
| const DbgValueInst* getDI() { return DI; } | |
| DebugLoc getdl() { return dl; } | |
| unsigned getSDNodeOrder() { return SDNodeOrder; } | |
| }; | |
| /// DanglingDebugInfoMap - Keeps track of dbg_values for which we have not | |
| /// yet seen the referent. We defer handling these until we do see it. | |
| DenseMap<const Value*, DanglingDebugInfo> DanglingDebugInfoMap; | |
| public: | |
| /// PendingLoads - Loads are not emitted to the program immediately. We bunch | |
| /// them up and then emit token factor nodes when possible. This allows us to | |
| /// get simple disambiguation between loads without worrying about alias | |
| /// analysis. | |
| SmallVector<SDValue, 8> PendingLoads; | |
| private: | |
| /// PendingExports - CopyToReg nodes that copy values to virtual registers | |
| /// for export to other blocks need to be emitted before any terminator | |
| /// instruction, but they have no other ordering requirements. We bunch them | |
| /// up and the emit a single tokenfactor for them just before terminator | |
| /// instructions. | |
| SmallVector<SDValue, 8> PendingExports; | |
| /// SDNodeOrder - A unique monotonically increasing number used to order the | |
| /// SDNodes we create. | |
| unsigned SDNodeOrder; | |
| /// Case - A struct to record the Value for a switch case, and the | |
| /// case's target basic block. | |
| struct Case { | |
| Constant* Low; | |
| Constant* High; | |
| MachineBasicBlock* BB; | |
| uint32_t ExtraWeight; | |
| Case() : Low(0), High(0), BB(0), ExtraWeight(0) { } | |
| Case(Constant* low, Constant* high, MachineBasicBlock* bb, | |
| uint32_t extraweight) : Low(low), High(high), BB(bb), | |
| ExtraWeight(extraweight) { } | |
| APInt size() const { | |
| const APInt &rHigh = cast<ConstantInt>(High)->getValue(); | |
| const APInt &rLow = cast<ConstantInt>(Low)->getValue(); | |
| return (rHigh - rLow + 1ULL); | |
| } | |
| }; | |
| struct CaseBits { | |
| uint64_t Mask; | |
| MachineBasicBlock* BB; | |
| unsigned Bits; | |
| CaseBits(uint64_t mask, MachineBasicBlock* bb, unsigned bits): | |
| Mask(mask), BB(bb), Bits(bits) { } | |
| }; | |
| typedef std::vector<Case> CaseVector; | |
| typedef std::vector<CaseBits> CaseBitsVector; | |
| typedef CaseVector::iterator CaseItr; | |
| typedef std::pair<CaseItr, CaseItr> CaseRange; | |
| /// CaseRec - A struct with ctor used in lowering switches to a binary tree | |
| /// of conditional branches. | |
| struct CaseRec { | |
| CaseRec(MachineBasicBlock *bb, const Constant *lt, const Constant *ge, | |
| CaseRange r) : | |
| CaseBB(bb), LT(lt), GE(ge), Range(r) {} | |
| /// CaseBB - The MBB in which to emit the compare and branch | |
| MachineBasicBlock *CaseBB; | |
| /// LT, GE - If nonzero, we know the current case value must be less-than or | |
| /// greater-than-or-equal-to these Constants. | |
| const Constant *LT; | |
| const Constant *GE; | |
| /// Range - A pair of iterators representing the range of case values to be | |
| /// processed at this point in the binary search tree. | |
| CaseRange Range; | |
| }; | |
| typedef std::vector<CaseRec> CaseRecVector; | |
| /// The comparison function for sorting the switch case values in the vector. | |
| /// WARNING: Case ranges should be disjoint! | |
| struct CaseCmp { | |
| bool operator()(const Case &C1, const Case &C2) { | |
| assert(isa<ConstantInt>(C1.Low) && isa<ConstantInt>(C2.High)); | |
| const ConstantInt* CI1 = cast<const ConstantInt>(C1.Low); | |
| const ConstantInt* CI2 = cast<const ConstantInt>(C2.High); | |
| return CI1->getValue().slt(CI2->getValue()); | |
| } | |
| }; | |
| struct CaseBitsCmp { | |
| bool operator()(const CaseBits &C1, const CaseBits &C2) { | |
| return C1.Bits > C2.Bits; | |
| } | |
| }; | |
| size_t Clusterify(CaseVector &Cases, const SwitchInst &SI); | |
| /// CaseBlock - This structure is used to communicate between | |
| /// SelectionDAGBuilder and SDISel for the code generation of additional basic | |
| /// blocks needed by multi-case switch statements. | |
| struct CaseBlock { | |
| CaseBlock(ISD::CondCode cc, const Value *cmplhs, const Value *cmprhs, | |
| const Value *cmpmiddle, | |
| MachineBasicBlock *truebb, MachineBasicBlock *falsebb, | |
| MachineBasicBlock *me, | |
| uint32_t trueweight = 0, uint32_t falseweight = 0) | |
| : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs), | |
| TrueBB(truebb), FalseBB(falsebb), ThisBB(me), | |
| TrueWeight(trueweight), FalseWeight(falseweight) { } | |
| // CC - the condition code to use for the case block's setcc node | |
| ISD::CondCode CC; | |
| // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit. | |
| // Emit by default LHS op RHS. MHS is used for range comparisons: | |
| // If MHS is not null: (LHS <= MHS) and (MHS <= RHS). | |
| const Value *CmpLHS, *CmpMHS, *CmpRHS; | |
| // TrueBB/FalseBB - the block to branch to if the setcc is true/false. | |
| MachineBasicBlock *TrueBB, *FalseBB; | |
| // ThisBB - the block into which to emit the code for the setcc and branches | |
| MachineBasicBlock *ThisBB; | |
| // TrueWeight/FalseWeight - branch weights. | |
| uint32_t TrueWeight, FalseWeight; | |
| }; | |
| struct JumpTable { | |
| JumpTable(unsigned R, unsigned J, MachineBasicBlock *M, | |
| MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {} | |
| /// Reg - the virtual register containing the index of the jump table entry | |
| //. to jump to. | |
| unsigned Reg; | |
| /// JTI - the JumpTableIndex for this jump table in the function. | |
| unsigned JTI; | |
| /// MBB - the MBB into which to emit the code for the indirect jump. | |
| MachineBasicBlock *MBB; | |
| /// Default - the MBB of the default bb, which is a successor of the range | |
| /// check MBB. This is when updating PHI nodes in successors. | |
| MachineBasicBlock *Default; | |
| }; | |
| struct JumpTableHeader { | |
| JumpTableHeader(APInt F, APInt L, const Value *SV, MachineBasicBlock *H, | |
| bool E = false): | |
| First(F), Last(L), SValue(SV), HeaderBB(H), Emitted(E) {} | |
| APInt First; | |
| APInt Last; | |
| const Value *SValue; | |
| MachineBasicBlock *HeaderBB; | |
| bool Emitted; | |
| }; | |
| typedef std::pair<JumpTableHeader, JumpTable> JumpTableBlock; | |
| struct BitTestCase { | |
| BitTestCase(uint64_t M, MachineBasicBlock* T, MachineBasicBlock* Tr): | |
| Mask(M), ThisBB(T), TargetBB(Tr) { } | |
| uint64_t Mask; | |
| MachineBasicBlock *ThisBB; | |
| MachineBasicBlock *TargetBB; | |
| }; | |
| typedef SmallVector<BitTestCase, 3> BitTestInfo; | |
| struct BitTestBlock { | |
| BitTestBlock(APInt F, APInt R, const Value* SV, | |
| unsigned Rg, EVT RgVT, bool E, | |
| MachineBasicBlock* P, MachineBasicBlock* D, | |
| const BitTestInfo& C): | |
| First(F), Range(R), SValue(SV), Reg(Rg), RegVT(RgVT), Emitted(E), | |
| Parent(P), Default(D), Cases(C) { } | |
| APInt First; | |
| APInt Range; | |
| const Value *SValue; | |
| unsigned Reg; | |
| EVT RegVT; | |
| bool Emitted; | |
| MachineBasicBlock *Parent; | |
| MachineBasicBlock *Default; | |
| BitTestInfo Cases; | |
| }; | |
| public: | |
| // TLI - This is information that describes the available target features we | |
| // need for lowering. This indicates when operations are unavailable, | |
| // implemented with a libcall, etc. | |
| const TargetMachine &TM; | |
| const TargetLowering &TLI; | |
| SelectionDAG &DAG; | |
| const TargetData *TD; | |
| AliasAnalysis *AA; | |
| /// SwitchCases - Vector of CaseBlock structures used to communicate | |
| /// SwitchInst code generation information. | |
| std::vector<CaseBlock> SwitchCases; | |
| /// JTCases - Vector of JumpTable structures used to communicate | |
| /// SwitchInst code generation information. | |
| std::vector<JumpTableBlock> JTCases; | |
| /// BitTestCases - Vector of BitTestBlock structures used to communicate | |
| /// SwitchInst code generation information. | |
| std::vector<BitTestBlock> BitTestCases; | |
| // Emit PHI-node-operand constants only once even if used by multiple | |
| // PHI nodes. | |
| DenseMap<const Constant *, unsigned> ConstantsOut; | |
| /// FuncInfo - Information about the function as a whole. | |
| /// | |
| FunctionLoweringInfo &FuncInfo; | |
| /// OptLevel - What optimization level we're generating code for. | |
| /// | |
| CodeGenOpt::Level OptLevel; | |
| /// GFI - Garbage collection metadata for the function. | |
| GCFunctionInfo *GFI; | |
| /// LPadToCallSiteMap - Map a landing pad to the call site indexes. | |
| DenseMap<MachineBasicBlock*, SmallVector<unsigned, 4> > LPadToCallSiteMap; | |
| /// HasTailCall - This is set to true if a call in the current | |
| /// block has been translated as a tail call. In this case, | |
| /// no subsequent DAG nodes should be created. | |
| /// | |
| bool HasTailCall; | |
| LLVMContext *Context; | |
| SelectionDAGBuilder(SelectionDAG &dag, FunctionLoweringInfo &funcinfo, | |
| CodeGenOpt::Level ol) | |
| : SDNodeOrder(0), TM(dag.getTarget()), TLI(dag.getTargetLoweringInfo()), | |
| DAG(dag), FuncInfo(funcinfo), OptLevel(ol), | |
| HasTailCall(false), Context(dag.getContext()) { | |
| } | |
| void init(GCFunctionInfo *gfi, AliasAnalysis &aa); | |
| /// clear - Clear out the current SelectionDAG and the associated | |
| /// state and prepare this SelectionDAGBuilder object to be used | |
| /// for a new block. This doesn't clear out information about | |
| /// additional blocks that are needed to complete switch lowering | |
| /// or PHI node updating; that information is cleared out as it is | |
| /// consumed. | |
| void clear(); | |
| /// clearDanglingDebugInfo - Clear the dangling debug information | |
| /// map. This function is seperated from the clear so that debug | |
| /// information that is dangling in a basic block can be properly | |
| /// resolved in a different basic block. This allows the | |
| /// SelectionDAG to resolve dangling debug information attached | |
| /// to PHI nodes. | |
| void clearDanglingDebugInfo(); | |
| /// getRoot - Return the current virtual root of the Selection DAG, | |
| /// flushing any PendingLoad items. This must be done before emitting | |
| /// a store or any other node that may need to be ordered after any | |
| /// prior load instructions. | |
| /// | |
| SDValue getRoot(); | |
| /// getControlRoot - Similar to getRoot, but instead of flushing all the | |
| /// PendingLoad items, flush all the PendingExports items. It is necessary | |
| /// to do this before emitting a terminator instruction. | |
| /// | |
| SDValue getControlRoot(); | |
| DebugLoc getCurDebugLoc() const { return CurDebugLoc; } | |
| unsigned getSDNodeOrder() const { return SDNodeOrder; } | |
| void CopyValueToVirtualRegister(const Value *V, unsigned Reg); | |
| /// AssignOrderingToNode - Assign an ordering to the node. The order is gotten | |
| /// from how the code appeared in the source. The ordering is used by the | |
| /// scheduler to effectively turn off scheduling. | |
| void AssignOrderingToNode(const SDNode *Node); | |
| void visit(const Instruction &I); | |
| void visit(unsigned Opcode, const User &I); | |
| // resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V, | |
| // generate the debug data structures now that we've seen its definition. | |
| void resolveDanglingDebugInfo(const Value *V, SDValue Val); | |
| SDValue getValue(const Value *V); | |
| SDValue getNonRegisterValue(const Value *V); | |
| SDValue getValueImpl(const Value *V); | |
| void setValue(const Value *V, SDValue NewN) { | |
| SDValue &N = NodeMap[V]; | |
| assert(N.getNode() == 0 && "Already set a value for this node!"); | |
| N = NewN; | |
| } | |
| void setUnusedArgValue(const Value *V, SDValue NewN) { | |
| SDValue &N = UnusedArgNodeMap[V]; | |
| assert(N.getNode() == 0 && "Already set a value for this node!"); | |
| N = NewN; | |
| } | |
| void FindMergedConditions(const Value *Cond, MachineBasicBlock *TBB, | |
| MachineBasicBlock *FBB, MachineBasicBlock *CurBB, | |
| MachineBasicBlock *SwitchBB, unsigned Opc); | |
| void EmitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB, | |
| MachineBasicBlock *FBB, | |
| MachineBasicBlock *CurBB, | |
| MachineBasicBlock *SwitchBB); | |
| bool ShouldEmitAsBranches(const std::vector<CaseBlock> &Cases); | |
| bool isExportableFromCurrentBlock(const Value *V, const BasicBlock *FromBB); | |
| void CopyToExportRegsIfNeeded(const Value *V); | |
| void ExportFromCurrentBlock(const Value *V); | |
| void LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool IsTailCall, | |
| MachineBasicBlock *LandingPad = NULL); | |
| /// UpdateSplitBlock - When an MBB was split during scheduling, update the | |
| /// references that ned to refer to the last resulting block. | |
| void UpdateSplitBlock(MachineBasicBlock *First, MachineBasicBlock *Last); | |
| private: | |
| // Terminator instructions. | |
| void visitRet(const ReturnInst &I); | |
| void visitBr(const BranchInst &I); | |
| void visitSwitch(const SwitchInst &I); | |
| void visitIndirectBr(const IndirectBrInst &I); | |
| void visitUnreachable(const UnreachableInst &I) { /* noop */ } | |
| // Helpers for visitSwitch | |
| bool handleSmallSwitchRange(CaseRec& CR, | |
| CaseRecVector& WorkList, | |
| const Value* SV, | |
| MachineBasicBlock* Default, | |
| MachineBasicBlock *SwitchBB); | |
| bool handleJTSwitchCase(CaseRec& CR, | |
| CaseRecVector& WorkList, | |
| const Value* SV, | |
| MachineBasicBlock* Default, | |
| MachineBasicBlock *SwitchBB); | |
| bool handleBTSplitSwitchCase(CaseRec& CR, | |
| CaseRecVector& WorkList, | |
| const Value* SV, | |
| MachineBasicBlock* Default, | |
| MachineBasicBlock *SwitchBB); | |
| bool handleBitTestsSwitchCase(CaseRec& CR, | |
| CaseRecVector& WorkList, | |
| const Value* SV, | |
| MachineBasicBlock* Default, | |
| MachineBasicBlock *SwitchBB); | |
| uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst); | |
| void addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst, | |
| uint32_t Weight = 0); | |
| public: | |
| void visitSwitchCase(CaseBlock &CB, | |
| MachineBasicBlock *SwitchBB); | |
| void visitBitTestHeader(BitTestBlock &B, MachineBasicBlock *SwitchBB); | |
| void visitBitTestCase(BitTestBlock &BB, | |
| MachineBasicBlock* NextMBB, | |
| unsigned Reg, | |
| BitTestCase &B, | |
| MachineBasicBlock *SwitchBB); | |
| void visitJumpTable(JumpTable &JT); | |
| void visitJumpTableHeader(JumpTable &JT, JumpTableHeader &JTH, | |
| MachineBasicBlock *SwitchBB); | |
| private: | |
| // These all get lowered before this pass. | |
| void visitInvoke(const InvokeInst &I); | |
| void visitResume(const ResumeInst &I); | |
| void visitUnwind(const UnwindInst &I); | |
| void visitBinary(const User &I, unsigned OpCode); | |
| void visitShift(const User &I, unsigned Opcode); | |
| void visitAdd(const User &I) { visitBinary(I, ISD::ADD); } | |
| void visitFAdd(const User &I) { visitBinary(I, ISD::FADD); } | |
| void visitSub(const User &I) { visitBinary(I, ISD::SUB); } | |
| void visitFSub(const User &I); | |
| void visitMul(const User &I) { visitBinary(I, ISD::MUL); } | |
| void visitFMul(const User &I) { visitBinary(I, ISD::FMUL); } | |
| void visitURem(const User &I) { visitBinary(I, ISD::UREM); } | |
| void visitSRem(const User &I) { visitBinary(I, ISD::SREM); } | |
| void visitFRem(const User &I) { visitBinary(I, ISD::FREM); } | |
| void visitUDiv(const User &I) { visitBinary(I, ISD::UDIV); } | |
| void visitSDiv(const User &I); | |
| void visitFDiv(const User &I) { visitBinary(I, ISD::FDIV); } | |
| void visitAnd (const User &I) { visitBinary(I, ISD::AND); } | |
| void visitOr (const User &I) { visitBinary(I, ISD::OR); } | |
| void visitXor (const User &I) { visitBinary(I, ISD::XOR); } | |
| void visitShl (const User &I) { visitShift(I, ISD::SHL); } | |
| void visitLShr(const User &I) { visitShift(I, ISD::SRL); } | |
| void visitAShr(const User &I) { visitShift(I, ISD::SRA); } | |
| void visitICmp(const User &I); | |
| void visitFCmp(const User &I); | |
| // Visit the conversion instructions | |
| void visitTrunc(const User &I); | |
| void visitZExt(const User &I); | |
| void visitSExt(const User &I); | |
| void visitFPTrunc(const User &I); | |
| void visitFPExt(const User &I); | |
| void visitFPToUI(const User &I); | |
| void visitFPToSI(const User &I); | |
| void visitUIToFP(const User &I); | |
| void visitSIToFP(const User &I); | |
| void visitPtrToInt(const User &I); | |
| void visitIntToPtr(const User &I); | |
| void visitBitCast(const User &I); | |
| void visitExtractElement(const User &I); | |
| void visitInsertElement(const User &I); | |
| void visitShuffleVector(const User &I); | |
| void visitExtractValue(const ExtractValueInst &I); | |
| void visitInsertValue(const InsertValueInst &I); | |
| void visitLandingPad(const LandingPadInst &I); | |
| void visitGetElementPtr(const User &I); | |
| void visitSelect(const User &I); | |
| void visitAlloca(const AllocaInst &I); | |
| void visitLoad(const LoadInst &I); | |
| void visitStore(const StoreInst &I); | |
| void visitAtomicCmpXchg(const AtomicCmpXchgInst &I); | |
| void visitAtomicRMW(const AtomicRMWInst &I); | |
| void visitFence(const FenceInst &I); | |
| void visitPHI(const PHINode &I); | |
| void visitCall(const CallInst &I); | |
| bool visitMemCmpCall(const CallInst &I); | |
| void visitAtomicLoad(const LoadInst &I); | |
| void visitAtomicStore(const StoreInst &I); | |
| void visitInlineAsm(ImmutableCallSite CS); | |
| const char *visitIntrinsicCall(const CallInst &I, unsigned Intrinsic); | |
| void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); | |
| void visitPow(const CallInst &I); | |
| void visitExp2(const CallInst &I); | |
| void visitExp(const CallInst &I); | |
| void visitLog(const CallInst &I); | |
| void visitLog2(const CallInst &I); | |
| void visitLog10(const CallInst &I); | |
| void visitVAStart(const CallInst &I); | |
| void visitVAArg(const VAArgInst &I); | |
| void visitVAEnd(const CallInst &I); | |
| void visitVACopy(const CallInst &I); | |
| void visitUserOp1(const Instruction &I) { | |
| llvm_unreachable("UserOp1 should not exist at instruction selection time!"); | |
| } | |
| void visitUserOp2(const Instruction &I) { | |
| llvm_unreachable("UserOp2 should not exist at instruction selection time!"); | |
| } | |
| const char *implVisitAluOverflow(const CallInst &I, ISD::NodeType Op); | |
| void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); | |
| /// EmitFuncArgumentDbgValue - If V is an function argument then create | |
| /// corresponding DBG_VALUE machine instruction for it now. At the end of | |
| /// instruction selection, they will be inserted to the entry BB. | |
| bool EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, | |
| int64_t Offset, const SDValue &N); | |
| }; | |
| } // end namespace llvm | |
| #endif |