You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			152 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			152 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | //===-- HexagonISelDAGToDAG.h -----------------------------------*- C++ -*-===//
 | ||
|  | //
 | ||
|  | //                     The LLVM Compiler Infrastructure
 | ||
|  | //
 | ||
|  | // This file is distributed under the University of Illinois Open Source
 | ||
|  | // License. See LICENSE.TXT for details.
 | ||
|  | //
 | ||
|  | //===----------------------------------------------------------------------===//
 | ||
|  | // Hexagon specific code to select Hexagon machine instructions for
 | ||
|  | // SelectionDAG operations.
 | ||
|  | //===----------------------------------------------------------------------===//
 | ||
|  | 
 | ||
|  | #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
 | ||
|  | #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
 | ||
|  | 
 | ||
|  | #include "HexagonSubtarget.h"
 | ||
|  | #include "HexagonTargetMachine.h"
 | ||
|  | #include "llvm/ADT/StringRef.h"
 | ||
|  | #include "llvm/CodeGen/SelectionDAG.h"
 | ||
|  | #include "llvm/CodeGen/SelectionDAGISel.h"
 | ||
|  | #include "llvm/Support/CodeGen.h"
 | ||
|  | 
 | ||
|  | #include <vector>
 | ||
|  | 
 | ||
|  | namespace llvm { | ||
|  | class MachineFunction; | ||
|  | class HexagonInstrInfo; | ||
|  | class HexagonRegisterInfo; | ||
|  | class HexagonTargetLowering; | ||
|  | 
 | ||
|  | class HexagonDAGToDAGISel : public SelectionDAGISel { | ||
|  |   const HexagonSubtarget *HST; | ||
|  |   const HexagonInstrInfo *HII; | ||
|  |   const HexagonRegisterInfo *HRI; | ||
|  | public: | ||
|  |   explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, | ||
|  |                                CodeGenOpt::Level OptLevel) | ||
|  |       : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr), | ||
|  |         HRI(nullptr) {} | ||
|  | 
 | ||
|  |   bool runOnMachineFunction(MachineFunction &MF) override { | ||
|  |     // Reset the subtarget each time through.
 | ||
|  |     HST = &MF.getSubtarget<HexagonSubtarget>(); | ||
|  |     HII = HST->getInstrInfo(); | ||
|  |     HRI = HST->getRegisterInfo(); | ||
|  |     SelectionDAGISel::runOnMachineFunction(MF); | ||
|  |     return true; | ||
|  |   } | ||
|  | 
 | ||
|  |   bool ComplexPatternFuncMutatesDAG() const override { | ||
|  |     return true; | ||
|  |   } | ||
|  |   void PreprocessISelDAG() override; | ||
|  |   void EmitFunctionEntryCode() override; | ||
|  | 
 | ||
|  |   void Select(SDNode *N) override; | ||
|  | 
 | ||
|  |   // Complex Pattern Selectors.
 | ||
|  |   inline bool SelectAddrGA(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAddrGP(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAnyImm(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAnyInt(SDValue &N, SDValue &R); | ||
|  |   bool SelectAnyImmediate(SDValue &N, SDValue &R, uint32_t LogAlign); | ||
|  |   bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP, | ||
|  |                            uint32_t LogAlign); | ||
|  |   bool SelectAddrFI(SDValue &N, SDValue &R); | ||
|  |   bool DetectUseSxtw(SDValue &N, SDValue &R); | ||
|  | 
 | ||
|  |   inline bool SelectAnyImm0(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAnyImm1(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAnyImm2(SDValue &N, SDValue &R); | ||
|  |   inline bool SelectAnyImm3(SDValue &N, SDValue &R); | ||
|  | 
 | ||
|  |   StringRef getPassName() const override { | ||
|  |     return "Hexagon DAG->DAG Pattern Instruction Selection"; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Generate a machine instruction node corresponding to the circ/brev
 | ||
|  |   // load intrinsic.
 | ||
|  |   MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN); | ||
|  |   // Given the circ/brev load intrinsic and the already generated machine
 | ||
|  |   // instruction, generate the appropriate store (that is a part of the
 | ||
|  |   // intrinsic's functionality).
 | ||
|  |   SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN); | ||
|  | 
 | ||
|  |   void SelectFrameIndex(SDNode *N); | ||
|  |   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
 | ||
|  |   /// inline asm expressions.
 | ||
|  |   bool SelectInlineAsmMemoryOperand(const SDValue &Op, | ||
|  |                                     unsigned ConstraintID, | ||
|  |                                     std::vector<SDValue> &OutOps) override; | ||
|  |   bool tryLoadOfLoadIntrinsic(LoadSDNode *N); | ||
|  |   void SelectLoad(SDNode *N); | ||
|  |   void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl); | ||
|  |   void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl); | ||
|  |   void SelectStore(SDNode *N); | ||
|  |   void SelectSHL(SDNode *N); | ||
|  |   void SelectZeroExtend(SDNode *N); | ||
|  |   void SelectIntrinsicWChain(SDNode *N); | ||
|  |   void SelectIntrinsicWOChain(SDNode *N); | ||
|  |   void SelectConstant(SDNode *N); | ||
|  |   void SelectConstantFP(SDNode *N); | ||
|  |   void SelectBitcast(SDNode *N); | ||
|  |   void SelectV65Gather(SDNode *N); | ||
|  |   void SelectV65GatherPred(SDNode *N); | ||
|  |   void SelectHVXDualOutput(SDNode *N); | ||
|  | 
 | ||
|  |   // Include the declarations autogenerated from the selection patterns.
 | ||
|  |   #define GET_DAGISEL_DECL
 | ||
|  |   #include "HexagonGenDAGISel.inc"
 | ||
|  | 
 | ||
|  | private: | ||
|  |   // This is really only to get access to ReplaceNode (which is a protected
 | ||
|  |   // member). Any other members used by HvxSelector can be moved around to
 | ||
|  |   // make them accessible).
 | ||
|  |   friend struct HvxSelector; | ||
|  | 
 | ||
|  |   SDValue selectUndef(const SDLoc &dl, MVT ResTy) { | ||
|  |     SDNode *U = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy); | ||
|  |     return SDValue(U, 0); | ||
|  |   } | ||
|  | 
 | ||
|  |   void SelectHvxShuffle(SDNode *N); | ||
|  |   void SelectHvxRor(SDNode *N); | ||
|  | 
 | ||
|  |   bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src); | ||
|  |   bool isAlignedMemNode(const MemSDNode *N) const; | ||
|  |   bool isSmallStackStore(const StoreSDNode *N) const; | ||
|  |   bool isPositiveHalfWord(const SDNode *N) const; | ||
|  |   bool hasOneUse(const SDNode *N) const; | ||
|  | 
 | ||
|  |   // DAG preprocessing functions.
 | ||
|  |   void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes); | ||
|  |   void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes); | ||
|  |   void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes); | ||
|  |   void ppHoistZextI1(std::vector<SDNode*> &&Nodes); | ||
|  | 
 | ||
|  |   SmallDenseMap<SDNode *,int> RootWeights; | ||
|  |   SmallDenseMap<SDNode *,int> RootHeights; | ||
|  |   SmallDenseMap<const Value *,int> GAUsesInFunction; | ||
|  |   int getWeight(SDNode *N); | ||
|  |   int getHeight(SDNode *N); | ||
|  |   SDValue getMultiplierForSHL(SDNode *N); | ||
|  |   SDValue factorOutPowerOf2(SDValue V, unsigned Power); | ||
|  |   unsigned getUsesInFunction(const Value *V); | ||
|  |   SDValue balanceSubTree(SDNode *N, bool Factorize = false); | ||
|  |   void rebalanceAddressTrees(); | ||
|  | }; // end HexagonDAGToDAGISel
 | ||
|  | } | ||
|  | 
 | ||
|  | #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
 |