LLVM API Documentation
00001 //===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the Base ARM implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef ARMBASEINSTRUCTIONINFO_H 00015 #define ARMBASEINSTRUCTIONINFO_H 00016 00017 #include "ARM.h" 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "llvm/ADT/SmallSet.h" 00020 #include "llvm/CodeGen/MachineInstrBuilder.h" 00021 #include "llvm/Target/TargetInstrInfo.h" 00022 00023 #define GET_INSTRINFO_HEADER 00024 #include "ARMGenInstrInfo.inc" 00025 00026 namespace llvm { 00027 class ARMSubtarget; 00028 class ARMBaseRegisterInfo; 00029 00030 class ARMBaseInstrInfo : public ARMGenInstrInfo { 00031 const ARMSubtarget &Subtarget; 00032 00033 protected: 00034 // Can be only subclassed. 00035 explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 00036 00037 public: 00038 // Return whether the target has an explicit NOP encoding. 00039 bool hasNOP() const; 00040 00041 // Return the non-pre/post incrementing version of 'Opc'. Return 0 00042 // if there is not such an opcode. 00043 virtual unsigned getUnindexedOpcode(unsigned Opc) const =0; 00044 00045 virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 00046 MachineBasicBlock::iterator &MBBI, 00047 LiveVariables *LV) const; 00048 00049 virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0; 00050 const ARMSubtarget &getSubtarget() const { return Subtarget; } 00051 00052 ScheduleHazardRecognizer * 00053 CreateTargetHazardRecognizer(const TargetMachine *TM, 00054 const ScheduleDAG *DAG) const; 00055 00056 ScheduleHazardRecognizer * 00057 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 00058 const ScheduleDAG *DAG) const; 00059 00060 // Branch analysis. 00061 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 00062 MachineBasicBlock *&FBB, 00063 SmallVectorImpl<MachineOperand> &Cond, 00064 bool AllowModify = false) const; 00065 virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; 00066 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 00067 MachineBasicBlock *FBB, 00068 const SmallVectorImpl<MachineOperand> &Cond, 00069 DebugLoc DL) const; 00070 00071 virtual 00072 bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; 00073 00074 // Predication support. 00075 bool isPredicated(const MachineInstr *MI) const; 00076 00077 ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { 00078 int PIdx = MI->findFirstPredOperandIdx(); 00079 return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() 00080 : ARMCC::AL; 00081 } 00082 00083 virtual 00084 bool PredicateInstruction(MachineInstr *MI, 00085 const SmallVectorImpl<MachineOperand> &Pred) const; 00086 00087 virtual 00088 bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 00089 const SmallVectorImpl<MachineOperand> &Pred2) const; 00090 00091 virtual bool DefinesPredicate(MachineInstr *MI, 00092 std::vector<MachineOperand> &Pred) const; 00093 00094 virtual bool isPredicable(MachineInstr *MI) const; 00095 00096 /// GetInstSize - Returns the size of the specified MachineInstr. 00097 /// 00098 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; 00099 00100 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, 00101 int &FrameIndex) const; 00102 virtual unsigned isStoreToStackSlot(const MachineInstr *MI, 00103 int &FrameIndex) const; 00104 virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, 00105 int &FrameIndex) const; 00106 virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, 00107 int &FrameIndex) const; 00108 00109 virtual void copyPhysReg(MachineBasicBlock &MBB, 00110 MachineBasicBlock::iterator I, DebugLoc DL, 00111 unsigned DestReg, unsigned SrcReg, 00112 bool KillSrc) const; 00113 00114 virtual void storeRegToStackSlot(MachineBasicBlock &MBB, 00115 MachineBasicBlock::iterator MBBI, 00116 unsigned SrcReg, bool isKill, int FrameIndex, 00117 const TargetRegisterClass *RC, 00118 const TargetRegisterInfo *TRI) const; 00119 00120 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, 00121 MachineBasicBlock::iterator MBBI, 00122 unsigned DestReg, int FrameIndex, 00123 const TargetRegisterClass *RC, 00124 const TargetRegisterInfo *TRI) const; 00125 00126 virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const; 00127 00128 virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, 00129 int FrameIx, 00130 uint64_t Offset, 00131 const MDNode *MDPtr, 00132 DebugLoc DL) const; 00133 00134 virtual void reMaterialize(MachineBasicBlock &MBB, 00135 MachineBasicBlock::iterator MI, 00136 unsigned DestReg, unsigned SubIdx, 00137 const MachineInstr *Orig, 00138 const TargetRegisterInfo &TRI) const; 00139 00140 MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; 00141 00142 MachineInstr *commuteInstruction(MachineInstr*, bool=false) const; 00143 00144 const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg, 00145 unsigned SubIdx, unsigned State, 00146 const TargetRegisterInfo *TRI) const; 00147 00148 virtual bool produceSameValue(const MachineInstr *MI0, 00149 const MachineInstr *MI1, 00150 const MachineRegisterInfo *MRI) const; 00151 00152 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to 00153 /// determine if two loads are loading from the same base address. It should 00154 /// only return true if the base pointers are the same and the only 00155 /// differences between the two addresses is the offset. It also returns the 00156 /// offsets by reference. 00157 virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 00158 int64_t &Offset1, int64_t &Offset2)const; 00159 00160 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to 00161 /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads 00162 /// should be scheduled togther. On some targets if two loads are loading from 00163 /// addresses in the same cache line, it's better if they are scheduled 00164 /// together. This function takes two integers that represent the load offsets 00165 /// from the common base address. It returns true if it decides it's desirable 00166 /// to schedule the two loads together. "NumLoads" is the number of loads that 00167 /// have already been scheduled after Load1. 00168 virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 00169 int64_t Offset1, int64_t Offset2, 00170 unsigned NumLoads) const; 00171 00172 virtual bool isSchedulingBoundary(const MachineInstr *MI, 00173 const MachineBasicBlock *MBB, 00174 const MachineFunction &MF) const; 00175 00176 virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, 00177 unsigned NumCycles, unsigned ExtraPredCycles, 00178 const BranchProbability &Probability) const; 00179 00180 virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 00181 unsigned NumT, unsigned ExtraT, 00182 MachineBasicBlock &FMBB, 00183 unsigned NumF, unsigned ExtraF, 00184 const BranchProbability &Probability) const; 00185 00186 virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 00187 unsigned NumCycles, 00188 const BranchProbability 00189 &Probability) const { 00190 return NumCycles == 1; 00191 } 00192 00193 virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 00194 MachineBasicBlock &FMBB) const; 00195 00196 /// analyzeCompare - For a comparison instruction, return the source registers 00197 /// in SrcReg and SrcReg2 if having two register operands, and the value it 00198 /// compares against in CmpValue. Return true if the comparison instruction 00199 /// can be analyzed. 00200 virtual bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 00201 unsigned &SrcReg2, int &CmpMask, 00202 int &CmpValue) const; 00203 00204 /// optimizeCompareInstr - Convert the instruction to set the zero flag so 00205 /// that we can remove a "comparison with zero"; Remove a redundant CMP 00206 /// instruction if the flags can be updated in the same way by an earlier 00207 /// instruction such as SUB. 00208 virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 00209 unsigned SrcReg2, int CmpMask, int CmpValue, 00210 const MachineRegisterInfo *MRI) const; 00211 00212 virtual bool analyzeSelect(const MachineInstr *MI, 00213 SmallVectorImpl<MachineOperand> &Cond, 00214 unsigned &TrueOp, unsigned &FalseOp, 00215 bool &Optimizable) const; 00216 00217 virtual MachineInstr *optimizeSelect(MachineInstr *MI, bool) const; 00218 00219 /// FoldImmediate - 'Reg' is known to be defined by a move immediate 00220 /// instruction, try to fold the immediate into the use instruction. 00221 virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 00222 unsigned Reg, MachineRegisterInfo *MRI) const; 00223 00224 virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, 00225 const MachineInstr *MI) const; 00226 00227 virtual 00228 int getOperandLatency(const InstrItineraryData *ItinData, 00229 const MachineInstr *DefMI, unsigned DefIdx, 00230 const MachineInstr *UseMI, unsigned UseIdx) const; 00231 virtual 00232 int getOperandLatency(const InstrItineraryData *ItinData, 00233 SDNode *DefNode, unsigned DefIdx, 00234 SDNode *UseNode, unsigned UseIdx) const; 00235 00236 /// VFP/NEON execution domains. 00237 std::pair<uint16_t, uint16_t> 00238 getExecutionDomain(const MachineInstr *MI) const; 00239 void setExecutionDomain(MachineInstr *MI, unsigned Domain) const; 00240 00241 unsigned getPartialRegUpdateClearance(const MachineInstr*, unsigned, 00242 const TargetRegisterInfo*) const; 00243 void breakPartialRegDependency(MachineBasicBlock::iterator, unsigned, 00244 const TargetRegisterInfo *TRI) const; 00245 /// Get the number of addresses by LDM or VLDM or zero for unknown. 00246 unsigned getNumLDMAddresses(const MachineInstr *MI) const; 00247 00248 private: 00249 unsigned getInstBundleLength(const MachineInstr *MI) const; 00250 00251 int getVLDMDefCycle(const InstrItineraryData *ItinData, 00252 const MCInstrDesc &DefMCID, 00253 unsigned DefClass, 00254 unsigned DefIdx, unsigned DefAlign) const; 00255 int getLDMDefCycle(const InstrItineraryData *ItinData, 00256 const MCInstrDesc &DefMCID, 00257 unsigned DefClass, 00258 unsigned DefIdx, unsigned DefAlign) const; 00259 int getVSTMUseCycle(const InstrItineraryData *ItinData, 00260 const MCInstrDesc &UseMCID, 00261 unsigned UseClass, 00262 unsigned UseIdx, unsigned UseAlign) const; 00263 int getSTMUseCycle(const InstrItineraryData *ItinData, 00264 const MCInstrDesc &UseMCID, 00265 unsigned UseClass, 00266 unsigned UseIdx, unsigned UseAlign) const; 00267 int getOperandLatency(const InstrItineraryData *ItinData, 00268 const MCInstrDesc &DefMCID, 00269 unsigned DefIdx, unsigned DefAlign, 00270 const MCInstrDesc &UseMCID, 00271 unsigned UseIdx, unsigned UseAlign) const; 00272 00273 unsigned getInstrLatency(const InstrItineraryData *ItinData, 00274 const MachineInstr *MI, 00275 unsigned *PredCost = 0) const; 00276 00277 int getInstrLatency(const InstrItineraryData *ItinData, 00278 SDNode *Node) const; 00279 00280 bool hasHighOperandLatency(const InstrItineraryData *ItinData, 00281 const MachineRegisterInfo *MRI, 00282 const MachineInstr *DefMI, unsigned DefIdx, 00283 const MachineInstr *UseMI, unsigned UseIdx) const; 00284 bool hasLowDefLatency(const InstrItineraryData *ItinData, 00285 const MachineInstr *DefMI, unsigned DefIdx) const; 00286 00287 /// verifyInstruction - Perform target specific instruction verification. 00288 bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const; 00289 00290 private: 00291 /// Modeling special VFP / NEON fp MLA / MLS hazards. 00292 00293 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 00294 /// MLx table. 00295 DenseMap<unsigned, unsigned> MLxEntryMap; 00296 00297 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 00298 /// stalls when scheduled together with fp MLA / MLS opcodes. 00299 SmallSet<unsigned, 16> MLxHazardOpcodes; 00300 00301 public: 00302 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 00303 /// instruction. 00304 bool isFpMLxInstruction(unsigned Opcode) const { 00305 return MLxEntryMap.count(Opcode); 00306 } 00307 00308 /// isFpMLxInstruction - This version also returns the multiply opcode and the 00309 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 00310 /// the MLX instructions with an extra lane operand. 00311 bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 00312 unsigned &AddSubOpc, bool &NegAcc, 00313 bool &HasLane) const; 00314 00315 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 00316 /// will cause stalls when scheduled after (within 4-cycle window) a fp 00317 /// MLA / MLS instruction. 00318 bool canCauseFpMLxStall(unsigned Opcode) const { 00319 return MLxHazardOpcodes.count(Opcode); 00320 } 00321 00322 /// Returns true if the instruction has a shift by immediate that can be 00323 /// executed in one cycle less. 00324 bool isSwiftFastImmShift(const MachineInstr *MI) const; 00325 }; 00326 00327 static inline 00328 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 00329 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 00330 } 00331 00332 static inline 00333 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 00334 return MIB.addReg(0); 00335 } 00336 00337 static inline 00338 const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB, 00339 bool isDead = false) { 00340 return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead)); 00341 } 00342 00343 static inline 00344 const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) { 00345 return MIB.addReg(0); 00346 } 00347 00348 static inline 00349 bool isUncondBranchOpcode(int Opc) { 00350 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 00351 } 00352 00353 static inline 00354 bool isCondBranchOpcode(int Opc) { 00355 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 00356 } 00357 00358 static inline 00359 bool isJumpTableBranchOpcode(int Opc) { 00360 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd || 00361 Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT; 00362 } 00363 00364 static inline 00365 bool isIndirectBranchOpcode(int Opc) { 00366 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 00367 } 00368 00369 /// getInstrPredicate - If instruction is predicated, returns its predicate 00370 /// condition, otherwise returns AL. It also returns the condition code 00371 /// register by reference. 00372 ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg); 00373 00374 int getMatchingCondBranchOpcode(int Opc); 00375 00376 /// Determine if MI can be folded into an ARM MOVCC instruction, and return the 00377 /// opcode of the SSA instruction representing the conditional MI. 00378 unsigned canFoldARMInstrIntoMOVCC(unsigned Reg, 00379 MachineInstr *&MI, 00380 const MachineRegisterInfo &MRI); 00381 00382 /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether 00383 /// the instruction is encoded with an 'S' bit is determined by the optional 00384 /// CPSR def operand. 00385 unsigned convertAddSubFlagsOpcode(unsigned OldOpc); 00386 00387 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 00388 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 00389 /// code. 00390 void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 00391 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 00392 unsigned DestReg, unsigned BaseReg, int NumBytes, 00393 ARMCC::CondCodes Pred, unsigned PredReg, 00394 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 00395 00396 void emitT2RegPlusImmediate(MachineBasicBlock &MBB, 00397 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 00398 unsigned DestReg, unsigned BaseReg, int NumBytes, 00399 ARMCC::CondCodes Pred, unsigned PredReg, 00400 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 00401 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 00402 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 00403 unsigned DestReg, unsigned BaseReg, 00404 int NumBytes, const TargetInstrInfo &TII, 00405 const ARMBaseRegisterInfo& MRI, 00406 unsigned MIFlags = 0); 00407 00408 00409 /// rewriteARMFrameIndex / rewriteT2FrameIndex - 00410 /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 00411 /// offset could not be handled directly in MI, and return the left-over 00412 /// portion by reference. 00413 bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 00414 unsigned FrameReg, int &Offset, 00415 const ARMBaseInstrInfo &TII); 00416 00417 bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 00418 unsigned FrameReg, int &Offset, 00419 const ARMBaseInstrInfo &TII); 00420 00421 } // End llvm namespace 00422 00423 #endif