forked from OSchip/llvm-project
[Hexagon] Create HexagonISelDAGToDAG.h, NFC
llvm-svn: 317904
This commit is contained in:
parent
b8c68c67dc
commit
89765acc6c
|
|
@ -12,6 +12,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "Hexagon.h"
|
#include "Hexagon.h"
|
||||||
|
#include "HexagonISelDAGToDAG.h"
|
||||||
#include "HexagonISelLowering.h"
|
#include "HexagonISelLowering.h"
|
||||||
#include "HexagonMachineFunctionInfo.h"
|
#include "HexagonMachineFunctionInfo.h"
|
||||||
#include "HexagonTargetMachine.h"
|
#include "HexagonTargetMachine.h"
|
||||||
|
|
@ -50,116 +51,9 @@ static cl::opt<bool> CheckSingleUse("hexagon-isel-su", cl::Hidden,
|
||||||
// Instruction Selector Implementation
|
// Instruction Selector Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
#define GET_DAGISEL_BODY HexagonDAGToDAGISel
|
||||||
/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
|
|
||||||
/// instructions for SelectionDAG operations.
|
|
||||||
///
|
|
||||||
namespace {
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
|
||||||
#include "HexagonGenDAGISel.inc"
|
#include "HexagonGenDAGISel.inc"
|
||||||
|
|
||||||
private:
|
|
||||||
bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
|
|
||||||
bool isOrEquivalentToAdd(const SDNode *N) const;
|
|
||||||
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
|
|
||||||
} // end anonymous namespace
|
|
||||||
|
|
||||||
|
|
||||||
/// createHexagonISelDag - This pass converts a legalized DAG into a
|
/// createHexagonISelDag - This pass converts a legalized DAG into a
|
||||||
/// Hexagon-specific DAG, ready for instruction scheduling.
|
/// Hexagon-specific DAG, ready for instruction scheduling.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
//===-- 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 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 SelectVectorShuffle(SDNode *N);
|
||||||
|
|
||||||
|
// Include the pieces autogenerated from the target description.
|
||||||
|
#define GET_DAGISEL_DECL
|
||||||
|
#include "HexagonGenDAGISel.inc"
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
|
||||||
|
bool isOrEquivalentToAdd(const SDNode *N) const;
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue